设计模式之禅之设计模式-组合模式

一:组合模式的定义
        --->组合模式(Composite Pattern)也叫合成模式,有时又叫做部分-整体模式(Part-Whole),主要是用来描述部分与整体的关系
        --->将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

二:组合模式的角色
        ● Component抽象构件角色
                定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性
        ● Leaf叶子构件
                叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。
        ● Composite树枝构件
                树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构。

三:组合模式的应用

组合模式的优点:
        ● 高层模块调用简单
                一棵树形机构中的所有节点都是Component,局部和整体对调用者来说没有任何区别,也就是说,高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。
        ● 节点自由增加
                使用了组合模式后,我们可以看看,如果想增加一个树枝节点、树叶节点是不是都很容易,只要找到它的父节点就成,非常容易扩展,符合开闭原则,对以后的维护非常有利。

组合模式的缺点:
        组合模式有一个非常明显的缺点,看到我们在场景类中的定义,提到树叶和树枝使用时的定义了吗?直接使用了实现类!这在面向接口编程上是很不恰当的,与依赖倒置原则冲突,读者在使用的时候要考虑清楚,它限制了你接口的影响范围。

四:组合模式的应用场景
● 维护和展示部分-整体关系的场景,如树形菜单、文件和文件夹管理。
● 从一个整体中能够独立出部分模块或功能的场景。
● 只要是树形结构,就要考虑使用组合模式,这个一定要记住,只要是要体现局部和整体的关系的时候,而且这种关系还可能比较深,考虑一下组合模式吧。

五:组合模式的最佳实践
        组合模式有两种不同的实现:透明模式和安全模式
                ● 透明模式:透明模式是把用来组合使用的方法放到抽象类中,比如add()、remove()以及getChildren等方法(顺便说一下,getChildren一般返回的结果为Iterable的实现类,很多,大家可以看JDK的帮助),不管叶子对象还是树枝对象都有相同的结构
                ● 安全模式:它是把树枝节点和树叶节点彻底分开,树枝节点单独拥有用来组合的方法,这种方法比较安全,我们的例子使用了安全模式。

        组合模式的案例:
                -->大家常用的XML结构也是一个树形结构
                -->我们自身的亲戚关系也是一种树形结构
                -->部门的职位等级,页面权限菜单显示搜是树形结构

六:组合模式的例子
【1】公共的抽象类

 1 package com.yeepay.sxf.template16;
 2 /**
 3  * 组合模式的抽象类
 4  *
 5  *抽象模型中角色的公共部分
 6  *比如:共有的属性,共有的行为方法
 7  * @author sxf
 8  *
 9  */
10 public abstract class ComponentCorp {
11     //公司的每个人都有名字
12     private String name="";
13     //公司的每个人都有职位
14     private String position="";
15     //公司的每个人都有薪水
16     private int salary=0;
17
18     //抽象类的构造函数
19     public ComponentCorp(String name,String postion,Integer salary){
20         this.name=name;
21         this.position=postion;
22         this.salary=salary;
23     }
24
25     //获取个人信息
26     public String getInfo(){
27         StringBuffer buffer=new StringBuffer();
28         buffer.append("姓名:"+this.name+"\t");
29         buffer.append("职位:"+this.position+"\t");
30         buffer.append("薪水:"+this.salary+"\t");
31         return buffer.toString();
32     }
33
34 }

View Code

【2】树叶节点

 1 package com.yeepay.sxf.template16;
 2 /**
 3  * 组合模式中的,部件
 4  * 树叶节点。仅含有公共部分的属性和方法
 5  * @author sxf
 6  *
 7  */
 8 public class Leaf extends ComponentCorp{
 9
10     //构造函数
11     public Leaf(String name, String postion, Integer salary) {
12         super(name, postion, salary);
13     }
14
15 }

View Code

【3】树枝节点

 1 package com.yeepay.sxf.template16;
 2
 3 import java.util.ArrayList;
 4 import java.util.List;
 5
 6 /**
 7  * 组合模式的整体部分
 8  *
 9  * 树枝节点
10  * 除去公共部分,有自己特色的部分
11  * @author sxf
12  *
13  */
14 public class Branch extends ComponentCorp {
15     //该节点是可以拥有下属节点的特权(除共有属性行为方法之外,特有的行为)
16     private List<ComponentCorp> subordinateList=new ArrayList<ComponentCorp>();
17     //构造函数
18     public Branch(String name, String postion, Integer salary) {
19         super(name, postion, salary);
20     }
21     //添加下属节点,(除共有属性行为方法之外,特有的行为)
22     public void addBordinate(ComponentCorp componentCorp){
23         this.subordinateList.add(componentCorp);
24     }
25     //获取自己的下属
26     public List<ComponentCorp> getBordinate(){
27         return this.subordinateList;
28     }
29
30 }

View Code

【4】测试类

 1 package com.yeepay.sxf.template16;
 2 /***
 3  * 客户端测试
 4  */
 5 import java.util.List;
 6
 7 /**
 8  * 客户端测试
 9  * @author sxf
10  *
11  */
12 public class ClientTest {
13     public static void main(String[] args) {
14         //生成小兵
15         Leaf bin1=new Leaf("兵1", "技术员", 1000);
16         Leaf bin2=new Leaf("兵2", "技术员", 1000);
17         Leaf bin3=new Leaf("兵3", "销售员", 500);
18         Leaf bin4=new Leaf("兵4", "销售员", 500);
19         //生成部分领导
20         Branch order1=new Branch("领导1", "技术经理", 10000);
21         Branch order2=new Branch("领导2", "销售经理", 8000);
22         //生成老板
23         Branch leard=new Branch("老板", "总经理", 200000);
24
25         //进行组合
26         order1.addBordinate(bin1);
27         order1.addBordinate(bin2);
28         order2.addBordinate(bin3);
29         order2.addBordinate(bin4);
30         leard.addBordinate(order1);
31         leard.addBordinate(order2);
32
33         //进行遍历
34         List<ComponentCorp> list=leard.getBordinate();
35         for(ComponentCorp c:list){
36
37             if(c instanceof Leaf){
38                 //是兵
39                 System.out.println("ClientTest.main(兵)"+c.getInfo());
40             }else if(c instanceof Branch){
41                 //是领导
42                 System.out.println("ClientTest.main(领导)"+c.getInfo());
43             }
44         }
45     }
46 }

View Code

 

时间: 2024-09-24 12:28:27

设计模式之禅之设计模式-组合模式的相关文章

.NET设计模式(11):组合模式(Composite Pattern)

概述 组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦. 意图 将对象组合成树形结构以表示"部分-整体"的层次结构.Composite模式使得用户对单个对象和组合对象的使用具有一致性.[GOF <设计模式>] 结构图 图1 Composite模式结构图 生活中的例子 组合模式将对象组合成树形结构以表示"部分-整体"的层次结构

设计模式的C++实现之组合模式

解决的问题: 我们PC用到的文件系统,其实就是我们数据结构里的树形结构,我们处理树中的每个节点时,其实 不用考虑他是叶子节点还是根节点,因为他们的成员函数都是一样的,这个就是组合模式的精髓.他模糊了简单元素和复杂 元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦. 将 对象组合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 注明:树形结构里的叶子节点也有左右孩子,只不过他的孩子都是空.

设计模式之禅之设计模式-桥梁模式

一:桥梁模式定义        --->桥梁模式(Bridge Pattern)也叫做桥接模式,是一个比较简单的模式        --->将抽象和实现解耦,使得两者可以独立地变化. 二:桥梁模式角色 ● Abstraction--抽象化角色        它的主要职责是定义出该角色的行为,同时保存一个对实现化角色的引用,该角色一般是抽象类.● Implementor--实现化角色        它是接口或者抽象类,定义角色必需的行为和属性.● RefinedAbstraction--修正抽象

设计模式之禅之设计模式-备忘录模式

<一:备忘录模式的定义        --->备忘录模式(Memento Pattern)提供了一种弥补真实世界缺陷的方法,让"后悔药"在程序的世界中真实可行        --->在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.        --->通俗地说,备忘录模式就是一个对象的备份模式,提供了一种程序数据的备份方法 二:备忘录模式的角色 ● Originator发起人角色      

设计模式之禅之设计模式-装饰者模式

一:装饰模式的定义        --->动态地给一个对象添加一些额外的职责.就增加功能来说,装饰模式相比生成子类更为灵活.        --->如果大家还记得代理模式,那么很容易看懂这个类图,装饰类的作用也就是一个特殊的代理类.        --->在装饰模式中,必然有一个最基本.最核心.最原始的接口或抽象类充当Component抽象构件 二:装饰模式的角色        ● Component抽象构件                Component是一个接口或者是抽象类,就是定

设计模式之禅之设计模式-策略模式

一:策略模式的定义        --->是一种比较简单的模式,也叫做政策模式        --->定义一组算法,将每个算法都封装起来,并且使它们之间可以互换 二:策略模式的三个角色 ● Context封装角色        --->它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略.算法的直接访问,封装可能存在的变化.● Strategy抽象策略角色        --->策略.算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性● ConcreteStr

设计模式之禅之设计模式-迭代器模式

一:迭代器模式的定义        --->迭代器模式(Iterator Pattern)目前已经是一个没落的模式,基本上没人会单独写一个迭代器,除非是产品性质的开发        --->它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节.        --->迭代器是为容器服务的,那什么是容器呢? 能容纳对象的所有类型都可以称之为容器,例如Collection集合类型.Set类型等,迭代器模式就是为解决遍历这些容器中的元素而诞生的        --->迭

设计模式之禅之设计模式-模板方法模式

一:模板方法模式的定义        --->定义一个操作中的算法的框架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤.        --->模板方法模式确实非常简单,仅仅使用了Java的继承机制,但它是一个应用非常广泛的模式.其中,AbstractClass叫做抽象模板,它的方法分为两类:        ● 基本方法                基本方法也叫做基本操作,是由子类实现的方法,并且在模板方法被调用.        ● 模板方法   

设计模式之禅之设计模式-建造者模式

一:建造者模式的定义        --->建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示        ● Product产品类                通常是实现了模板方法模式,也就是有模板方法和基本方法,这个参考模板方法模式.例子中的BenzModel和BMWModel就属于产品类.        ● Builder抽象建造者                规范产品的组建,一般是由子类