设计模式------组合模式

[code]
这个标题说的是一种模式。。。又叫~~树模式~~整体部分模式
这个模式是为了同一树中的叶子节点和非叶子节点。。。

组合模式场景:
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;
}
}


[/code]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值