软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 架构设计 -> 大话设计模式—组合模式 -> 正文阅读

[架构设计]大话设计模式—组合模式


组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
大话设计模式中程杰老师给出的定义是,组合模式:将对象组合成树形结构以表示”部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性
组合模式结构图:
[img]http://img.blog.csdn.net/20160401203730645
首先,让我们通过过一个简单的实例来简单了解一下组合模式做基本的用法。实例演示了一个组织中员工的层次结构。
创建Employee类:
package com.exercise.composite;

import java.util.ArrayList;
import java.util.List;

public class Employee {

    private String name;
    private String dept;
    private int salary;
    private List<Employee> subordinates;//部下

    //constructor
    public Employee(String name, String dept, int salary,
            List<Employee> subordinates) {
        super();
        this.name = name;
        this.dept = dept;
        this.salary = salary;
        this.subordinates = subordinates;
        subordinates = new ArrayList<Employee>();
    }


    public Employee(String name, String dept, int salary) {
        super();
        this.name = name;
        this.dept = dept;
        this.salary = salary;
        subordinates = new ArrayList<Employee>();
    }


    public void add(Employee e){
        subordinates.add(e);
    }

    public void remove(Employee e){
        subordinates.remove(e);
    }

    public List<Employee> getSubordinates(){
        return subordinates;
    }

    public String toString(){
          return "Employee :[ Name : " + name 
          + ", dept : " + dept + ", salary :"
          + salary + " ]";
       } 
}

测试类:
package com.exercise.composite;
/**
 * 使用Employee来创建和打印员工的层次结构
 * @author lmb
 *
 */
public class CompositePatternDemo {

    public static void main(String[] args) {

      Employee CEO = new Employee("John","CEO", 30000);
      Employee headSales = new Employee("Robert","Head Sales", 20000);
      Employee headMarketing = new Employee("Michel","Head Marketing", 20000);
      Employee clerk1 = new Employee("Laura","Marketing", 10000);
      Employee clerk2 = new Employee("Bob","Marketing", 10000);
      Employee salesExecutive1 = new Employee("Richard","Sales", 10000);
      Employee salesExecutive2 = new Employee("Rob","Sales", 10000);

      CEO.add(headSales);
      CEO.add(headMarketing);
      headSales.add(salesExecutive1);
      headSales.add(salesExecutive2);
      headMarketing.add(clerk1);
      headMarketing.add(clerk2);

      //打印该组织的所有员工
      System.out.println("-------------------公司员工情况----------------------");
      System.out.println(CEO);
      for (Employee headEmployee : CEO.getSubordinates()) {
          //打印CEO的直属一级部下
         System.out.println(headEmployee);
         for (Employee employee : headEmployee.getSubordinates()) {
             //打印CEO的二级部下
            System.out.println(employee);
         }
      } 

    }

}

运行结果:
[img]http://img.blog.csdn.net/20160401202040795
使用场景:
需求中是体现部分与整体层次结构的时候,以及当我们希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时。简而言之,就是涉及到部分、整体场景时,如树形菜单,文件、文件夹的管理。
主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
一般在工作中说起部分和总体我们想到最多的大概就是总公司和分公司了,如果我们需要做一套办公管理系统,并且总公司的人力资源部、财务部等的办公挂历功能在所有的分公司也都要有,我们该怎么实现?
功能实现:
[img]http://img.blog.csdn.net/20160401203941865
抽象公司类或接口
package com.composite;

public abstract class Company {

    protected String name;

    public Company(String name){
        this.name = name;
    }

    public abstract void add(Company company);//add
    public abstract void remove(Company company);//remove
    public abstract void display(int depth);//display
    public abstract void lineofDuty();//line of duty

}

具体公司类(树枝节点)
package com.composite;

import java.util.ArrayList;
import java.util.List;

public class ConcreteCompany extends Company {

    private List<Company> childrenCompany = new ArrayList<Company>();

    public ConcreteCompany(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {
        childrenCompany.add(company);
    }

    @Override
    public void display(int depth) {
        System.out.println("第 " + depth + " 层的机构名为: " + name);
        for (Company c : childrenCompany) {
            c.display(depth + 1);
        }
    }

    @Override
    public void lineofDuty() {
        for (Company c : childrenCompany) {
            c.lineofDuty();
        }
    }

    @Override
    public void remove(Company company) {
        childrenCompany.remove(company);
    }

}

财务部和人力资源部(树叶节点)
package com.composite;

public class HRDepartment extends Company {

    public HRDepartment(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {

    }

    @Override
    public void display(int depth) {
        System.out.println("第 " + depth + " 层的机构名为: " + name);
    }

    @Override
    public void lineofDuty() {
        System.out.println(name + "    负责员工招聘管理培训");
    }

    @Override
    public void remove(Company company) {

    }

}
package com.composite;

public class FinanceDepartment extends Company {

    public FinanceDepartment(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {

    }

    @Override
    public void display(int depth) {
        System.out.println("第 " + depth + " 层的机构名为: " + name);
    }

    @Override
    public void lineofDuty() {
        System.out.println(name + "   负责公司财务收支管理");
    }

    @Override
    public void remove(Company company) {

    }

}

测试方法
package com.composite;

public class CompositePatternDemo {

    public static void main(String[] args) {

        //一个总公司
        ConcreteCompany root = new ConcreteCompany("北京总公司");
        root.add(new HRDepartment("总公司人力资源部"));
        root.add(new FinanceDepartment("总公司财务部"));

        //三个子公司
        ConcreteCompany com1 = new ConcreteCompany("广州分公司");
        com1.add(new HRDepartment("广州分公司人力资源部"));
        com1.add(new FinanceDepartment("广州分公司财务部"));
        root.add(com1);

        ConcreteCompany com2 = new ConcreteCompany("杭州分公司");
        com2.add(new HRDepartment("杭州分公司人力资源部"));
        com2.add(new FinanceDepartment("杭州分公司财务部"));
        root.add(com2);

        ConcreteCompany com3 = new ConcreteCompany("深圳分公司");
        com3.add(new HRDepartment("深圳分公司人力资源部"));
        com3.add(new FinanceDepartment("深圳分公司财务部"));
        root.add(com3);

        System.out.println("-------公司结构图--------");
        root.display(1);
        System.out.println("----------各部门职责----------");
        root.lineofDuty();



    }

}

运行结果:
[img]http://img.blog.csdn.net/20160401220046224
这样,通过组合模式我们就定义了包含人力资源部和财务部这些基本对象和分公司等组合对象的类层次结构。

基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,在客户代码中,任何用到基本对象的地方都可以使用组合对象了。组合模式让客户可以一致的使用组合结构和单个对象。

应用实例:

1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作符也可以是操作树、操作符和另一个操作数。
2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。

优点:

1、高层模块调用简单。
2、节点自由增加。

缺点:

在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-04-02 20:54:52  
架构设计 最新文章
Opengl教程之读取obj并绘制在picturecontro
读《企业应用架构模式》第五章并发
StepbyStepintoSpring(IOC)
设计模式(2)用例图之一
使用实体组件系统(ECS)开发”吃方块”游戏实
编程学习之简单工厂模式与策略模式
Invalidprojectdescription.
基于Redis实现分布式消息队列(2)
《开源框架那点事儿15》:借船下海还是造船
原型模式——浅复制和深复制
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年1日历
2018-1-16 21:16:07
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --