您现在的位置是:首页 >技术教程 >设计模式之组合模式网站首页技术教程

设计模式之组合模式

King Gigi. 2024-06-17 11:28:30
简介设计模式之组合模式

1、组合模式基本介绍

组合模式是一种结构型设计模式,它允许你将对象组合成树状结构,并且能像使用单个对象一样使用组合对象和单个对象。

组合模式中,有两种类型的对象:单个对象(Leaf)组合对象(Composite)

组合对象可以包含其他组合对象或单个对象,从而形成树状结构

组合对象中通常会定义添加、删除、获取子对象等操作,而单个对象没有这些操作。

2、场景推导

业务场景:现在需要展示某个组织机构的层级结构,如公司的部门、子部门和员工等等。

在这种情况下,组织机构可以被视为一个组合对象,而部门、子部门和员工可以被视为单个对象。

  • 抽象组件

    //抽象组件
    interface Component {
        void show();
    }
    
  • 叶子节点

    //叶子节点
    class Leaf implements Component {
        private String name;
    
        public Leaf(String name) {
            this.name = name;
        }
    
        @Override
        public void show() {
            System.out.println(name);
        }
    }
    
  • 组合节点

    //组合节点
    class Composite implements Component {
        private String name;
    
        private List<Component> children = new ArrayList<>();
    
        public Composite(String name) {
            this.name = name;
        }
    
        public void add(Component component) {
            children.add(component);
        }
    
        public void remove(Component component) {
            children.remove(component);
        }
    
        @Override
        public void show() {
            System.out.println(name);
            for (Component component : children) {
                component.show();
            }
        }
    }
    
  • 客户端

    public class AppTest {
        public static void main(String[] args) throws Exception {
            // 构建组织机构的层级结构
            Composite root = new Composite("公司");
            Composite department1 = new Composite("部门1");
            Composite department2 = new Composite("部门2");
            Composite subDepartment1 = new Composite("子部门1");
            Leaf employee1 = new Leaf("员工1");
            Leaf employee2 = new Leaf("员工2");
            Leaf employee3 = new Leaf("员工3");
    
            root.add(department1);
            root.add(department2);
            department1.add(subDepartment1);
            subDepartment1.add(employee1);
            subDepartment1.add(employee2);
            department2.add(employee3);
    
            // 展示组织机构的层级结构
            root.show();
        }
    }
    
  • 运行结果

    公司
    部门1
    子部门1
    员工1
    员工2
    部门2
    员工3
    
    Process finished with exit code 0
    

在上面的栗子中,我们创建了抽象组件 Component 接口来定义组合对象和单个对象的通用方法。

  • 叶子节点 Leaf 表示单个对象,而组合节点 Composite 表示组合对象。
  • 我们将组合节点中的子节点存储在一个 List 中,从而实现了层级结构。
  • 在 Composite 中,我们实现了添加、删除和展示子节点的操作,而在 Leaf 中,我们只实现了展示自身的操作

UML图

在这里插入图片描述

3、最佳实践

业务需求:

假设在电商平台上有一些商品,这些商品可以被分为两类:单品和组合商品。

单品是指仅由一个商品组成的商品,而组合商品是指由多个商品组合而成的商品。

这里使用组合模式来实现这种商品的分类。

  • 首先定义一个商品接口,包含获取商品名称、获取商品价格等方法:

    interface Product {
        String getName();
        double getPrice();
    }
    
  • 然后定义一个单品类,实现商品接口:

    class SingleProduct implements Product {
        private String name;
        private double price;
    
        public SingleProduct(String name, double price) {
            this.name = name;
            this.price = price;
        }
    
        @Override
        public String getName() {
            return name;
        }
    
        @Override
        public double getPrice() {
            return price;
        }
    }
    
  • 接下来定义一个组合商品类,它包含多个子商品,实现商品接口:

    class CompositeProduct implements Product {
        private String name;
        private List<Product> products = new ArrayList<>();
    
        public CompositeProduct(String name) {
            this.name = name;
        }
    
        public void addProduct(Product product) {
            products.add(product);
        }
    
        public void removeProduct(Product product) {
            products.remove(product);
        }
    
        @Override
        public String getName() {
            return name;
        }
    
        @Override
        public double getPrice() {
            double totalPrice = 0;
            for (Product product : products) {
                totalPrice += product.getPrice();
            }
            return totalPrice;
        }
    }
    
  • 客户端

    public class AppTest2 {
        public static void main(String[] args) throws Exception {
            CompositeProduct root = new CompositeProduct("苹果全家桶");
            Product product1 = new SingleProduct("手机", 188.00);
            Product product2 = new SingleProduct("平板", 288.00);
            Product product3 = new SingleProduct("笔记本", 168.00);
    
            root.addProduct(product1);
            root.addProduct(product2);
            root.addProduct(product3);
    
            System.out.println(root.getName());
            System.out.println(root.getPrice());
        }
    
  • 运行结果

    苹果全家桶
    644.0
    
    Process finished with exit code 0
    

通过组合模式,可以方便地创建和管理多个商品的组合,而不需要考虑它们是单品还是组合商品,简化了代码的实现和维护。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。