zoukankan      html  css  js  c++  java
  • 设计模式(八)组合模式 Composite

    • 组合模式:

      允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

      组合模式适用于创建复杂的对象,这个对象包含某些个别的对象以及这些对象的组合。

      从操作的角度而言,客户端对于 个别对象/组合 的操作是一致的。

    • 模拟场景

      如图所示,总公司下属有多个部门,而子公司可以视为多个部门的组合。

      整个数据结构呈树状,完美契合组合模式的应用场景。

    • UML:

      在这个场景中:

    1. 个别对象 -> 人事部(HRDepartment)和财务部(FinanceDepartment)
    2. 个别对象的组合 -> 公司(Company)
    3. 无论是 Company 还是 Department,对于 Client 而言,都被当做 CompanyItem 使用。
    4. 从树形结构来理解,Department 是叶节点,Company 是非叶节点。
    • 代码:
    @Data
    @AllArgsConstructor
    @ToString
    public abstract class CompanyItem {
    
        protected String name;
    
        protected void addCompanyItem(CompanyItem companyItem) {
            throw new UnsupportedOperationException("Not support to add companyItem");
        }
    
        protected void removeCompanyItem(CompanyItem companyItem) {
            throw new UnsupportedOperationException("Not support to remove companyItem");
        }
    
        protected abstract void lineOfDuty();
    
        protected abstract void showStructure(int depth);
    }
    public final class Company extends CompanyItem {
    
        private List<CompanyItem> childCompanyItems = new ArrayList<>();
    
        public Company(String name) {
            super(name);
        }
    
        @Override
        public void addCompanyItem(CompanyItem component) {
            childCompanyItems.add(component);
        }
    
        @Override
        public void removeCompanyItem(CompanyItem component) {
            childCompanyItems.remove(component);
        }
    
        @Override
        public void lineOfDuty() {
            childCompanyItems.forEach(companyItem -> companyItem.lineOfDuty());
        }
    
        @Override
        public void showStructure(int depth) {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < depth; ++i) {
                builder.append("-");
            }
            System.out.println(builder.append(name));
            childCompanyItems.forEach(companyItem -> companyItem.showStructure(depth + 1));
        }
    }
    public final class FinanceDepartment extends CompanyItem {
    
        public FinanceDepartment(String name) {
            super(name);
        }
    
        @Override
        public void lineOfDuty() {
            System.out.println(name + ", treasurer is in charge of payroll");
        }
    
        @Override
        public void showStructure(int depth) {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < depth; ++i) {
                builder.append("-");
            }
            System.out.println(builder.append(name));
        }
    }
    public final class HRDepartment extends CompanyItem {
    
        public HRDepartment(String name) {
            super(name);
        }
    
        @Override
        public void lineOfDuty() {
            System.out.println(name + ", HR is responsible for recruiting new employees");
        }
    
        @Override
        public void showStructure(int depth) {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < depth; ++i) {
                builder.append("-");
            }
            System.out.println(builder.append(name));
        }
    }
    • 客户端调用:
        private CompanyItem createParentCompany() {
            CompanyItem parentCompany = new Company("Shanghai parent company");
            parentCompany.addCompanyItem(new HRDepartment("Parent company HR department"));
            CompanyItem southChildCompany = new Company("South child company");
            southChildCompany.addCompanyItem(new HRDepartment("South child company HR department"));
            parentCompany.addCompanyItem(southChildCompany);
            CompanyItem hongKongOffice = new Company("HongKong office");
            hongKongOffice.addCompanyItem(new FinanceDepartment("Hongkong office Finance department"));
            southChildCompany.addCompanyItem(hongKongOffice);
            parentCompany.addCompanyItem(new FinanceDepartment("Parent company Finance department"));
            return parentCompany;
        }
    
        @Test
        void testComposite() {
            CompanyItem parentCompany = createParentCompany();
            parentCompany.showStructure(1);
            System.out.println("===========================");
            parentCompany.lineOfDuty();
        }
    • 输出:

  • 相关阅读:
    多线程
    序列化
    IO流
    递归
    JAVA异常处理
    java常用类-StringBuffer,Integer,Character
    系统测试过程
    备份,健壮,文档,在线帮助,网络,稳定性测试
    异常测试/恢复性测试(可靠)
    配置测试
  • 原文地址:https://www.cnblogs.com/jing-an-feng-shao/p/10869709.html
Copyright © 2011-2022 走看看