设计模式(十)组合模式

版权声明:转载必须注明本文转自晓_晨的博客:http://blog.csdn.net/niunai112

导航

设计模式之六大设计原则
设计模式(一)单例模式
设计模式(二)工厂模式
设计模式(三)策略模式
设计模式(四)适配器模式
设计模式(五)享元模式
设计模式(六)建造者模式
设计模式(七)原型模式
设计模式(八)桥接模式
设计模式(九)外观模式
设计模式(十)组合模式
设计模式(十一)装饰器模式
设计模式(十二)代理模式
设计模式(十三)迭代器模式
设计模式(十四)观察者模式
设计模式(十五)中介者模式
设计模式(十六)命令模式
设计模式(十七)状态模式
设计模式(十八)访问者模式
设计模式(十九)责任链模式
设计模式(二十)解释器模式
设计模式(二十一)备忘录模式
设计模式(二十二)模板模式
设计模式总结篇(为什么要学习设计模式,学习设计模式的好处)

前言

组合模式是指将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
其实可以想象成数据结构中的树型结构一样,他们有公有的方法和属性,而特殊节点有自己特有的方法和属性。

例子

LZ就构造一颗树来说明这个问题,和树不一样的是,这个树形结构包含两种类型的节点,一个姑且叫一般节点【子,Leaf】,另一个叫不一般节点【父节点,Composite,(这里的父节点与通常树的父节点不同,只是说这个节点可以再包含子节点,而不是说这节点有子节点)】,不一般节点可以包含Component,而一般节点和不一般节点都是继承Component。仔细看看这句话,这句话已经说完了组合模式的精髓,看不大懂就对着例子来看。

/***
 *
 *@Author ChenjunWang
 *@Description:公共的抽象类
 *@Date: Created in 21:27 2018/3/29
 *@Modified By:
 *
 */
public abstract class Component {
    int val;//所有节点都有值
    public abstract void add(Component component);
    public abstract void remove(Component component);

    public abstract void show();
    
}




/***
 *
 *@Author ChenjunWang
 *@Description:父节点类
 *@Date: Created in 21:36 2018/3/29
 *@Modified By:
 *
 */
public class Composite extends Component{
    List<Component> list = new ArrayList<>();//有一个列表来包涵它的子节点

    public Composite(int val){
        this.val = val;//构造函数
    }

    @Override
    public void add(Component component) {
        list.add(component);//往列表中加节点

    }

    @Override
    public void remove(Component component) {

        list.remove(component);//删列表中的该节点
    }

    @Override
    public void show() {

        System.out.println(val);//若是父节点则输出值并遍历出她所有的子节点的值
        for (Component c : list){
            c.show();
        }

    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:叶子节点类
 *@Date: Created in 21:35 2018/3/29
 *@Modified By:
 *
 */
public class Leaf extends Component{

    public Leaf(int val){
        this.val = val;//构造函数
    }

    @Override
    public void add(Component component) {
//因为叶子节点不能添加,所有为空
    }

    @Override
    public void remove(Component component) {
//不能删除,为空
    }

    @Override
    public void show() {

//输出值
        System.out.println(val);
    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:
 *@Date: Created in 21:42 2018/3/29
 *@Modified By:
 *
 */
public class Test {


    public static void main(String[] args) {
        Component composite1 = new Composite(1);
        Component composite2 = new Composite(12);
        Component composite3 = new Composite(23);
        Component leaf = new Leaf(34);
        composite1.add(composite2);
        composite2.add(composite3);
        composite3.add(leaf);
        System.out.println("从父节点1开始show");
        composite1.show();
        System.out.println("从父节点3开始show");
        composite3.show();

    }
}
输出结果如下
---------------------------
从父节点1开始show
1
12
23
34
从父节点3开始show
23
34


UML图
composite

上面就是一个组合模式的实际应用,我们会发现,有一个问题,那就是子节点也有add和remove方法,但是实际上,它应该是不允许访问这方法的,不符合接口隔离原则。所以上面的为不安全的组合模式。那如何做到安全呢,

/***
 *
 *@Author ChenjunWang
 *@Description:公共的抽象类
 *@Date: Created in 21:27 2018/3/29
 *@Modified By:
 *
 */
public abstract class Component {
    int val;//所有节点都有值

    public abstract void show();
    
}




/***
 *
 *@Author ChenjunWang
 *@Description:父节点类
 *@Date: Created in 21:36 2018/3/29
 *@Modified By:
 *
 */
public class Composite extends Component{
    List<Component> list = new ArrayList<>();//有一个列表来包涵它的子节点

    public Composite(int val){
        this.val = val;//构造函数
    }

    
    public void add(Component component) {
        list.add(component);//往列表中加节点

    }

  
    public void remove(Component component) {

        list.remove(component);//删列表中的该节点
    }

    @Override
    public void show() {

        System.out.println(val);//若是父节点则输出值并遍历出她所有的子节点的值
        for (Component c : list){
            c.show();
        }

    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:叶子节点类
 *@Date: Created in 21:35 2018/3/29
 *@Modified By:
 *
 */
public class Leaf extends Component{

    public Leaf(int val){
        this.val = val;//构造函数
    }

  
    @Override
    public void show() {

//输出值
        System.out.println(val);
    }
}

/***
 *
 *@Author ChenjunWang
 *@Description:
 *@Date: Created in 21:42 2018/3/29
 *@Modified By:
 *
 */
public class Test {


    
    public static void main(String[] args) {
        Composite composite1 = new Composite(1);
        Composite composite2 = new Composite(12);
        Composite composite3 = new Composite(23);
        Component leaf = new Leaf(34);
        composite1.add(composite2);
        composite2.add(composite3);
        composite3.add(leaf);
        System.out.println("从父节点1开始show");
        composite1.show();
        System.out.println("从父节点3开始show");
        composite3.show();

    }
}
输出结果如下
---------------------------
从父节点1开始show
1
12
23
34
从父节点3开始show
23
34

这样就是安全组合模式了,子节点不再能调用到父节点的独有的方法,但是对于调用的人来说,他在使用中,不再能已抽象类声明了。

总结

优点

(1)组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器,将”客户代码与复杂的对象容器结构“解耦。
(2)更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。这一点符合开闭原则的要求,有利于系统的拓展和维护。

缺点

(1) 若使用安全的组合模式,得直接申明实现类,这在面向接口编程上是很不恰当的,与依赖倒置原则冲突。若使用不安全的组合模式,则违反接口隔离原则。
(2)使你的系统结构更加复杂。

Git地址

本篇实例Github地址:https://github.com/stackisok/Design-Pattern/tree/master/src/main/java/composite

回到最上方

有什么不懂或者不对的地方,欢迎留言。
喜欢LZ文章的小伙伴们,可以关注一波,也可以留言,LZ会回你们的。
觉得写得不错的小伙伴,欢迎转载,但请附上原文地址,谢谢_!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值