设计形式-组合模式

设计模式------组合模式
这个标题说的是一种模式。。。又叫~~树模式~~整体部分模式
这个模式是为了同一树中的叶子节点和非叶子节点。。。

组合模式场景:
1。买电脑的商家,可以卖单独配件也可以卖组装整机。
2。复制文件,可以一个一个文件复制黏贴还可以整个文件夹进行复制。
3。再比如文件编辑,可以给单个字加粗,变色,改字体,也可以给整段文件做同样的操作。

组合模式使得用户对单个对象和组合对象的使用具有一致性。

我们需要写树形结构:
先写一个烂的,然后改进
public interface IRoot{
  public String getInfo();
  public void add(IBranch branch);
  public add(ILeaf leaf);
  public ArrayList getChildren();
}
public interface IBranch{
  public String getInfo();
  public void add(IBranch branch);
  public add(ILeaf leaf);
  public ArrayList getChildren();
}

public interface ILeaf{
  public String getInfo();
}
三个接口写完了,看出问题来了。。。IRoot和IBranch居然里面内容一样。。。
其实根节点就是一种枝节点,而且如果你不考虑parent的话,那么根节点就只会关心本身和他的孩子,枝节点也是只关心本身和他的孩子。。所以改进去掉IRoot

再观察: 接口是为了什么。。。是提取共性的,那么观察下IBranch和ILeaf中居然都有getInfo(); 那么这个共性是不是应该封装起来下呢?
所以先把ILeaf改名为IInfo
public interface INode{ //携带信息的能力,叶子节点和分支节点的共性
  public String getInfo();
}
然后在IBranch中复用他
public interface IChildren{ //他拥有放入IInfo和得到孩子的能力
  public List<INode> children = new ArrayList<INode>();
  public void add(INode node); 
  public List getChildren(); //并且在此扩展自己的能力
}
//注意的是:虽然本身拥有List,但是本身不提供遍历能力哈,因为不建议程序员使用迭代器模式,java提供了,那么我们还是显示的遍历下算了,因为程序写起来简单。。。中庸才是王道,面向过程有时候还是好的,要遍历的话我们就是用递归,把函数分给每个子类呗。。。不过要知道这是面向过程的递归哈。。。。。。
public class Leaf implements INode{ //他是一个Node,仅此而已 .....
}

public class Branch implements INode,IChildren{//他是一个node,而且还能装孩子  ......
}

业务逻辑中的遍历:
public static String getTreeInfo(Branch root){
   ArrayList<INode> children = root.getChildren(); 
   String info = "";
   for(INode info : children){
       if(info instanceof Leaf){
            info = info+info.getInfo()+"\n";
       }else{
            info = info+s.getInfo()+"\n" + getTreeInfo((Branch)info);//看见没,这里还是可以用多态,他有两个接口就可以在这两个接口的能力中*转换       }
   }
  return info;
} 

下面的问题是:接口有必要吗?
如果你的IInfo接口的有许多不同的实现的话,那么接口当然有用,因为我们可以利用多态来扩展,但是这时如果不需要扩展,那么接口就多余了。。但是IInfo的实现就一种,那么用他干嘛啊。。。当然是用抽象类啦。。

改造:

public abstract class AbstractNode{ //叶子节点所需要的能力只是得到信息
  private String name = "";
  private String position = "";
  private int salary = 0;
  private AbstractNode parent;
  public Info(String name,String position,String salary){
     this.name=name;
     this.position = position;
     this.salary = salary;
  }
  public String getInfo(){
     String info = "姓名:"+this.name+"\t 职位:"+this.position+"\t薪水"+this.salary;
    return info;
  }
   public AbstractNode getParent(){ //新增,为了可以追溯到父亲
       return this.parent;
   }
   public void setParent(AbstractNode parent){
      this.parent = parent;
   }
}
public class Leaf extends AbstractNode{//继承是为了复用
   public Leaf(String name,String position,int salary){
      super(name,position,salary);
   }
}

public Branch extends AbstractNode{
   ArrayList<AbstractNode> children = new ArrayList<AbstractNode>();
    public Branch (String name,String position,int salary){
      super(name,position,salary);
   }
   public void add(AbstractNode t){
       t.setParent(this); //新增,为了反向引用
      this.children.add(t);
   }
   public ArrayList<AbstractNode> getChildren(){
      
      return this.children;
   } 
}









1 楼 502220545 2012-02-10  
你的设计模式讲解 要是带有UML图就更好了