JAVA设计模式学习10——组合模式

2019-03-07 23:51|来源: 网络

   这节开始学习结构模式,结构模式包括:组合模式、门面模式、适配器模式、代理模式、装饰模式、桥模式、享元模式。从组合模式开始学习。    

组合模式(Composite)就是把部分和整体的关系用树形的结构来表示,从而使客户端能够把部分对象和组合起来的对象采用同样的方式来看待。

树图结构一般包含一个根节点,若干个树枝和叶子节点。如下图:

   可以用一个类图描述树结构的静态结构,把根节点当做树枝节点来描述,同时和叶子节点具有共同的父类:  
   

树结构的类图,其实就是组合模式的简略类图,最上面为抽象节点,左下方为叶子节点,右下方为树枝节点,它含有其他的节点。

通过以上结构图可以看出,组合模式有以下角色:    

1、抽象构建角色(component):作为抽象角色,给组合对象的统一接口。

2、树叶构建角色(leaf):代表组合对象中的树叶对象。

3、树枝构建角色(composite):参加组合的所有子对象的对象,并给出树枝构构建对象的行为。

组合模式在现实中使用很常见,比如文件系统中目录和文件的组成,算式运算,android里面的view和viewgroup等控件,淘宝产品分类信息的展示等都是组合模式的例子。还有个故事:从前山里有座庙,庙里有个老和尚,老和尚对象小和尚讲故事说,从前山里有个庙......退出循环的条件是听厌烦了,或者讲的人讲累了。

这个模式的举例最多的是公司员工的例子。我们这里也以故事雇员为例子来描述:



  1. package composite;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-7-20下午5:11:41

  6. *描述:员工和领导的统一接口

  7. */  

  8. public interface Worker {  

  9.      

  10.    public void doSomething();  

  11.  

  12. }  


  1. package composite;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-7-20下午5:59:11

  6. *描述:普通员工类

  7. */  

  8. public class Employe implements Worker {  

  9.  

  10.    private String name;  

  11.      

  12.    public Employe(String name) {  

  13.        super();  

  14.        this.name = name;  

  15.    }  

  16.    @Override  

  17.    public void doSomething() {  

  18.        System.out.println(toString());  

  19.    }  

  20.  

  21.  

  22.    @Override  

  23.    public String toString() {  

  24.        // TODO Auto-generated method stub  

  25.        return "我叫"+getName()+",就一普通员工!";  

  26.    }  

  27.  

  28.    public String getName() {  

  29.        return name;  

  30.    }  

  31.  

  32.    public void setName(String name) {  

  33.        this.name = name;  

  34.    }    

  35.  

  36. }  


  1. package composite;  

  2.  

  3. import java.util.Iterator;  

  4. import java.util.List;  

  5. import java.util.concurrent.CopyOnWriteArrayList;  

  6.  

  7. /**

  8. *

  9. *作者:alaric

  10. *时间:2013-7-20下午5:14:50

  11. *描述:领导类

  12. */  

  13. public class Leader implements Worker {  

  14.    private List<Worker> workers = new CopyOnWriteArrayList<Worker>();    

  15.    private String name;  

  16.      

  17.    public Leader(String name) {  

  18.        super();  

  19.        this.name = name;  

  20.    }  

  21.    public void add(Worker worker){  

  22.        workers.add(worker);  

  23.    }  

  24.      

  25.    public void remove(Worker worker){  

  26.        workers.remove(worker);  

  27.    }  

  28.      

  29.    public Worker getChild(int i){  

  30.        return workers.get(i);  

  31.    }  

  32.    @Override  

  33.    public void doSomething() {  

  34.        System.out.println(toString());  

  35.        Iterator<Worker> it = workers.iterator();  

  36.        while(it.hasNext()){  

  37.            it.next().doSomething();  

  38.        }  

  39.              

  40.    }  

  41.  

  42.      

  43.    @Override  

  44.    public String toString() {  

  45.        // TODO Auto-generated method stub  

  46.        return "我叫"+getName()+", 我是一个领导,有 "+workers.size()+"下属。";  

  47.    }  

  48.    public String getName() {  

  49.        return name;  

  50.    }  

  51.  

  52.    public void setName(String name) {  

  53.        this.name = name;  

  54.    }  

  55.  

  56. }  


  1. package composite;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-7-20下午5:49:37

  6. *描述:测试类

  7. */  

  8. public class Client {  

  9.  

  10.    /**

  11.     *作者:alaric

  12.     *时间:2013-7-20下午5:49:32

  13.     *描述:

  14.     */  

  15.    public static void main(String[] args) {  

  16.        // TODO Auto-generated method stub  

  17.        Leader leader1 = new Leader("张三");  

  18.        Leader leader2 = new Leader("李四");  

  19.        Employe employe1 = new Employe("王五");  

  20.        Employe employe2 = new Employe("赵六");  

  21.        Employe employe3 = new Employe("陈七");  

  22.        Employe employe4 = new Employe("徐八");  

  23.        leader1.add(leader2);  

  24.        leader1.add(employe1);  

  25.        leader1.add(employe2);  

  26.        leader2.add(employe3);  

  27.        leader2.add(employe4);  

  28.        leader1.doSomething();  

  29.          

  30.    }  



运行结果如下:

我叫张三, 我是一个领导,有 3个直接下属。

我叫李四, 我是一个领导,有 2个直接下属。

我叫陈七,就一普通员工!

我叫徐八,就一普通员工!

我叫王五,就一普通员工!

我叫赵六,就一普通员工!

上面员工关系的的树形结构如下:


上面例子给出的组合模式抽象角色里,并没有管理子节点的方法,而是在树枝构建角色,这种模式使得叶子构建角色和树枝构建角色有区分,客户端要分别对待树叶构建角色和树枝构建角色,好处是客户端对叶子节点不会调用管理的方法,当调用时,在编译时就会报错,所以也称安全模式。相对安全模式,还有一种透明模式,就是在抽象角色里面添加管理方法,如下图:


这种做法是对客户端来说叶子和树枝都是一致的接口,相对透明,但是叶子节点在调用管理方法是编译时不会报错,运行时才报错,所以不够安全。两种做法均有利弊,使用时要根据具体情况而权衡。    

 
转自:http://alaric.iteye.com/blog/1910919

相关问答

更多
  • 其实我相信你做了3年的java一定了解你所说的设计模式和反射机制在程序早已用过了的把,只是自己平时没注意;设计模式主要是用项目管理,让人看起来通俗易懂.反射机制用到的地方呢也比较多,在用properties和JFreeChart等地方都用到.
  • 模式开扩了我们的视野,强化了我们面向对象编程的思维方式 提高代码的复杂度为代价来增强灵活性、可复用性 工厂模式根据工厂模式实现的类可以根据提供的数据 生成一组类中某一个类的实例,通常这组类有一个公共的 抽象父类或接口并且实现了相同的方法,但是这些方法针对不同 的数据进行了不同的操作。 首先需要定义一个基类,该类的子类通过不同的方法实现了 基类中的方法,然后需要定义一个工厂类,工厂类可以根据 条件生成不同子类的实例。 得到实例后,可以调用基类的方法而不必考虑到底 返回的是哪个子类的实例。 Factory(工厂 ...
  • 马学兵视频,W3C 教程,硅谷动力 视频教程等 先看视频,然后跟着做一遍。 最后下载一个 源码,尝试着模仿做几个 基本算入门了
  • 你是准备学习使用 还是说研究它的底层实现机制这些东西? 如果只是使用 可以暂时不了解这些 ,你也没有这么多精力来了解这么多 你先将框架中的东西用熟练 然后再去了解这些也不迟 spring 的 IOC aop hibernate的 延迟加载 缓存 ,mvc这些学习都需要学习 其实你学习不学习这几个框架都可以对设计模式进行学习 设计模式在日常的版本开发中好处很多 而且在面试的时候 考官也会问设计模式方面的知识
  • 一共23种设计模式! 引用《软件秘笈-设计模式那点事》书籍: 按照目的来分,设计模式可以分为创建型模式、结构型模式和行为型模式。 创建型模式用来处理对象的创建过程;结构型模式用来处理类或者对象的组合;行为型模式用来对类或对象怎样交互和怎样分配职责进行描述。 创建型模式用来处理对象的创建过程,主要包含以下5种设计模式:  工厂方法模式(Factory Method Pattern)  抽象工厂模式(Abstract Factory Pattern)  建造者模式(Builder Pattern)  原 ...
  • 一般来说电驴(verycd)里面可以下载,那里面的资源很多。希望这个对你有帮助
  • java mvc设计模式[2022-08-26]

    MVC模式写的 有是有 不过里面加入了简单工厂模式 呵呵不知道你要不要
  • 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。 java设计模式是当你在实际的系统当中遇到重构或者扩展的时候采取的一种对现有系统影响最小的一种措施。当然并不是一定要学这个东西,就像一个没上过学的人和上过学的人,在个人修养上面存在一定的差异,但是他们都 ...