Java设计模式(六)

rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml"> rel="themeData" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx"> rel="colorSchemeMapping" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml">

Java设计模式(六)

------------组合模式

引子

如果你正在为一个大公司服务,我保证你自己都有可能至今还搞不清楚你们公司庞大的组织结构,小的部门可能有几个人,大的部门有几十人,还有的部门下面还有子部门,子子部门(听起来都烦了,其实也不关心),如果有一天我们要做一个OA系统来描述这样一个组织结构了,他们许多的需求都是逐级下发的,那么我们面对一个如此复杂的结构应该如何应对呢?也许你就应该考虑一下组合模式了。

定义

组合模式------基本思想就是将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性

实现

角色

我们在这还是对应公司组织结构的例子,来分析组合模式中的各个角色。

Component

抽象构件角色(Component):它为组合中的对象声明接口,也可以为共有接口实现缺省

行为。

 

/**

 * 公司抽象结构 可能包括人和部门

 * @author Administrator

 *

 */

public abstract class AbstractStructure {

       public String name;

 

       public AbstractStructure(String name){

              this.name=name;

       }

       //抽象通用方法

       public abstract void receiveEmail();

       //组合模式通用方法

       public abstract void addChildren(AbstractStructure a);

       public abstract void removeChildren(AbstractStructure a);

       public abstract Iterator getChildren();

       public String getName() {

              return name;

       }

}

 

 

Composite

树枝构件角色(Composite):在组合中表示分支节点对象——有子节点,实现抽象构件

角色声明的接口;存储子部件。在例子中对应的是部门。

 

public class Department extends AbstractStructure {

       public Department(String name) {

              super(name);

       }

       private List<AbstractStructure> staffs = new ArrayList<AbstractStructure>();

 

       @Override

       public void addChildren(AbstractStructure a) {

              // TODO Auto-generated method stub

              staffs.add(a);

       }

       @Override

       public Iterator<AbstractStructure> getChildren() {

              // TODO Auto-generated method stub

              return staffs.iterator();

       }

       @Override

       public void receiveEmail() {

              // TODO Auto-generated method stub

              Iterator<AbstractStructure> iter = this.getChildren();

              while (iter.hasNext()) {

                     AbstractStructure a = iter.next();

                     a.receiveEmail();

                     //System.out.println(a.getName() + "收到了部门群发Email");

              }

       }

       @Override

       public void removeChildren(AbstractStructure a) {

              // TODO Auto-generated method stub

              staffs.remove(a);

       }

}

 

Leaf

树叶构件角色(Leaf):在组合中表示叶节点对象——没有子节点,实现抽象构件角色声

明的接口。在例子中对应的是职员。

 

public class Staff extends AbstractStructure {

       public Staff(String name) {

              super(name);

       }

       @Override

       public void addChildren(AbstractStructure a) {

              // TODO Auto-generated method stub

              System.out.println("不能对人员进行添加操作");

       }

       @Override

       public Iterator getChildren() {

              // TODO Auto-generated method stub

              System.out.println("职员不能进行该查询");

              return null;

       }

       @Override

       public void receiveEmail() {

              // TODO Auto-generated method stub

              System.out.println(this.name + "收到一封Emal");

       }

       @Override

       public void removeChildren(AbstractStructure a) {

              // TODO Auto-generated method stub

              System.out.println("不能对人员进行删除操作");

       }

}

 

客户端调用

 

public class MyTest {

       /**

        * @param args

        */

       public static void main(String[] args) {

              // TODO Auto-generated method stub

              AbstractStructure root = new Department("神州集团");

              AbstractStructure dp1 = new Department("项目一部");

              AbstractStructure dp2 = new Department("项目二部");

              AbstractStructure s1 = new Staff("张三");

              AbstractStructure s2 = new Staff("李四");

              AbstractStructure s3 = new Staff("王五");

              AbstractStructure s4 = new Staff("刘二");

              AbstractStructure s5 = new Staff("谢周三");

              AbstractStructure s6 = new Staff("曼联");

 

              root.addChildren(dp1);

              root.addChildren(dp2);

              dp1.addChildren(s1);

              dp1.addChildren(s3);

              dp1.addChildren(s2);

              dp1.addChildren(s4);

              dp2.addChildren(s5);

              dp2.addChildren(s6);

             

              root.receiveEmail();

//            dp1.receiveEmail();

//            s5.receiveEmail();

       }

}

 

打印结果:

          张三收到一封Email

          王五收到一封Email

          李四收到一封Email

          刘二收到一封Email

          谢周三收到一封Email

          曼联收到一封Email

 

总结

组合模式是一个应用非常广泛的设计模式,在许多其他的设计模式中都是用到了组合模式。它本身比较简单但是很有内涵,掌握了它对你的开发设计有很大的帮助。

模式优点

1.       使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。

2.       更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。

注意事项

1Composite模式中,是将“Add***Remove***方法和对象容器相关的方法”定义在“表示抽象对象的Component类”中,还是将其定义在“表示对象容器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题,需要仔细权衡结构,这又是必须付出的代价。

2Composite模式在具体实现中,可以让父对象中的子对象反向追溯:如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值