📜  复合设计模式

📅  最后修改于: 2021-09-10 02:38:17             🧑  作者: Mango

复合模式是一种分区设计模式,它描述了一组对象,这些对象的处理方式与同一类型对象的单个实例相同。复合的目的是将对象“组合”成树结构以表示部分-整体层次结构。它允许您拥有树结构并要求树结构中的每个节点执行任务。

  • 正如 Gof 所描述的那样,“将对象组合成树结构以表示部分-整体层次结构。 Composite 让客户可以统一处理单个对象和对象的组合”。
  • 在处理树结构数据时,程序员通常必须区分叶节点和分支。这使得代码更加复杂,因此容易出错。解决方案是一个允许统一处理复杂和原始对象的接口
  • 在面向对象的编程中,组合是一个对象,它被设计为一个或多个相似对象的组合,所有这些对象都表现出相似的功能。这被称为对象之间的“has-a”关系。

    关键概念是您可以操作对象的单个实例,就像操作一组对象一样。您可以对所有复合对象执行的操作通常具有最小公分母关系。
    复合模式有四个参与者:

    1. 组件 –组件声明组合中对象的接口以及用于访问和管理其子组件的接口。它还根据需要为所有类通用的接口实现默认行为。
    2. 叶 –叶定义组合中原始对象的行为。它代表组合中的叶对象。
    3. Composite – Composite 存储子组件并在组件接口中实现与子相关的操作。
    4. 客户端——客户端通过组件接口操作组合中的对象。

    客户端使用组件类接口与组合结构中的对象进行交互。如果接收者是叶子,则直接处理请求。如果接收者是一个组合,那么它通常会将请求转发到它的子组件,可能在转发之前和之后执行额外的操作。

    现实生活中的例子

    在一个组织中,它有总经理,总经理下可以有经理,经理下可以有开发人员。现在您可以设置树结构并要求每个节点执行诸如 getSalary() 之类的常见操作。
    复合设计模式以两种方式处理每个节点:
    1) Composite – Composite 意味着它下面可以有其他对象。
    2)叶子——叶子意味着它下面没有物体。

    树结构:

    树
    上图显示了一个典型的复合对象结构。如您所见,单个父级(即 Composite)可以有多个子级,但每个子级只能有一个父级。

    接口组件。Java

    public interface Employee
    {
        public void showEmployeeDetails();
    }
    

    叶子。Java

    public class Developer implements Employee
    {
        private String name;
        private long empId;
        private String position;
      
        public Developer(long empId, String name, String position)
        {
            this.empId = empId;
            this.name = name;
                    this.position = position;
        }
          
        @Override
        public void showEmployeeDetails() 
        {
            System.out.println(empId+" " +name+);
        }
    }
    

    叶子。Java

    public class Manager implements Employee
    {
        private String name;
        private long empId;
            private String position;
      
        public Manager(long empId, String name, String position)
        {
            this.empId = empId;
            this.name = name;
                    this.position = position;
        }
          
        @Override
        public void showEmployeeDetails() 
        {
            System.out.println(empId+" " +name);
        }
    }
    

    合成的。Java

    import java.util.ArrayList;
    import java.util.List;
      
    public class CompanyDirectory implements Employee
    {
        private List employeeList = new ArrayList();
           
        @Override
        public void showEmployeeDetails() 
        {
            for(Employee emp:employeeList)
            {
                emp.showEmployeeDetails();
            }
        }
           
        public void addEmployee(Employee emp)
        {
            employeeList.add(emp);
        }
           
        public void removeEmployee(Employee emp)
        {
            employeeList.remove(emp);
        }
    }
    

    客户。Java

    public class Company
    {
        public static void main (String[] args)
        {
            Developer dev1 = new Developer(100, "Lokesh Sharma", "Pro Developer");
            Developer dev2 = new Developer(101, "Vinay Sharma", "Developer");
            CompanyDirectory engDirectory = new CompanyDirectory();
            engDirectory.addEmployee(dev1);
            engDirectory.addEmployee(dev2);
              
            Manager man1 = new Manager(200, "Kushagra Garg", "SEO Manager");
            Manager man2 = new Manager(201, "Vikram Sharma ", "Kushagra's Manager");
              
            CompanyDirectory accDirectory = new CompanyDirectory();
            accDirectory.addEmployee(man1);
            accDirectory.addEmployee(man2);
          
            CompanyDirectory directory = new CompanyDirectory();
            directory.addEmployee(engDirectory);
            directory.addEmployee(accDirectory);
            directory.showEmployeeDetails();
        }
    }
    

    复合设计模式的 UML 图:

    复合设计-UML

    上面例子的完整运行代码:

    // A Java program to demonstrate working of
    // Composite Design Pattern with example 
    // of a company with different
    //  employee details
      
    import java.util.ArrayList;
    import java.util.List;
      
      
    // A common interface for all employee
    interface Employee
    {
        public void showEmployeeDetails();
    }
      
    class Developer implements Employee
    {
        private String name;
        private long empId;
        private String position;
          
        public Developer(long empId, String name, String position)
        {
            // Assign the Employee id,
            // name and the position
            this.empId = empId;
            this.name = name;
            this.position = position;
        }
          
        @Override
        public void showEmployeeDetails() 
        {
            System.out.println(empId+" " +name+ " " + position );
        }
    }
      
    class Manager implements Employee
    {
        private String name;
        private long empId;
        private String position;
       
        public Manager(long empId, String name, String position)
        {
            this.empId = empId;
            this.name = name;
            this.position = position;
        }
           
        @Override
        public void showEmployeeDetails() 
        {
            System.out.println(empId+" " +name+ " " + position );
        }
    }
      
      
    // Class used to get Employee List
    // and do the opertions like 
    // add or remove Employee
      
    class CompanyDirectory implements Employee
    {
        private List employeeList = new ArrayList();
            
        @Override
        public void showEmployeeDetails() 
        {
            for(Employee emp:employeeList)
            {
                emp.showEmployeeDetails();
            }
        }
            
        public void addEmployee(Employee emp)
        {
            employeeList.add(emp);
        }
            
        public void removeEmployee(Employee emp)
        {
            employeeList.remove(emp);
        }
    }
      
    // Driver class
    public class Company
    {
        public static void main (String[] args)
        {
            Developer dev1 = new Developer(100, "Lokesh Sharma", "Pro Developer");
            Developer dev2 = new Developer(101, "Vinay Sharma", "Developer");
            CompanyDirectory engDirectory = new CompanyDirectory();
            engDirectory.addEmployee(dev1);
            engDirectory.addEmployee(dev2);
               
            Manager man1 = new Manager(200, "Kushagra Garg", "SEO Manager");
            Manager man2 = new Manager(201, "Vikram Sharma ", "Kushagra's Manager");
               
            CompanyDirectory accDirectory = new CompanyDirectory();
            accDirectory.addEmployee(man1);
            accDirectory.addEmployee(man2);
           
            CompanyDirectory directory = new CompanyDirectory();
            directory.addEmployee(engDirectory);
            directory.addEmployee(accDirectory);
            directory.showEmployeeDetails();
        }
    }
    

    输出 :

    100 Lokesh Sharma Pro Developer
    101 Vinay Sharma Developer
    200 Kushagra Garg SEO Manager
    201 Vikram Sharma  Kushagra's Manager
    

    什么时候使用复合设计模式?

    当客户需要忽略对象的组合和单个对象之间的差异时,应该使用复合模式。如果程序员发现他们以相同的方式使用多个对象,并且通常有几乎相同的代码来处理每个对象,那么复合是一个不错的选择,在这种情况下,将基元和复合视为同构并不那么复杂。

    1. 更少的对象减少了内存使用量,它设法让我们远离与内存相关的错误,如Java.lang.OutOfMemoryError。
    2. 尽管在Java创建对象确实很快,但我们仍然可以通过共享对象来减少程序的执行时间。

    什么时候不使用复合设计模式?

    1. 复合设计模式使得限制复合组件的类型变得更加困难。因此,当您不想表示对象的完整或部分层次结构时,不应使用它。
    2. 复合设计模式会使设计过于笼统。限制复合材料的组件变得更加困难。有时您希望复合材料仅包含某些组件。使用 Composite,您不能依赖类型系统来为您强制执行这些约束。相反,您必须使用运行时检查。