定义:将对象组合成树形结构以表示“部分 - 整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

组合模式适合于树形数据结构,使用时可以应用多态或者递归处理树形数据结构。

该模式中包含 3 类角色:

  1. 抽象组件:叶节点和容器共同的接口。
  2. 叶节点(简单组件):树的基本结构,完成实际的业务逻辑。
  3. 容器(复合组件):由叶节点或容器组成的复杂结构。

代码实现

// 形状类   
public interface Shape {  
    int getX();  
    int getY();  
    double getArea();  
}
//基础形状  
public abstract class BaseShape implements Shape{  
    private int x;  
    private int y;  
  
    public BaseShape(int x, int y) {  
        this.x = x;  
        this.y = y;  
    }  
  
    @Override  
    public int getX() {  
        return x;  
    }  
  
    @Override  
    public int getY() {  
        return y;  
    }  
  
    @Override  
    public double getArea() {  
        return 0;  
    }  
}

叶节点

//圆形  
public class Circle extends BaseShape {  
    private int radius;  
  
    public Circle(int x, int y, int radius) {  
        super(x, y);  
        this.radius = radius;  
    }  
  
    @Override  
    public double getArea() {  
        return Math.PI * (Math.pow(radius, 1));  
    }  
}

//长方形  
public class Rectangle extends BaseShape{  
    private int width;  
    private int height;  
  
    public Rectangle(int x, int y, int width, int height) {  
        super(x, y);  
        this.width = width;  
        this.height = height;  
    }  
  
    @Override  
    public double getArea() {  
        return width+height;  
    }  
}

容器

// 复合形状  
public class CompoundShape extends BaseShape {  
    private List<Shape> shapes = new ArrayList<>();  
  
    public CompoundShape(Shape... shapes) {  
        super(0, 0);  
        this.shapes.addAll(List.of(shapes));  
    }  
  
    public void addShape(Shape shape) {  
        shapes.add(shape);  
    }  
  
    public void removeShape(Shape shape) {  
        shapes.remove(shape);  
    }  
  
    @Override  
    public int getX() {  
        int x = 0;  
        for (Shape child : shapes) {  
            x = Math.min(x, child.getX());  
        }  
        return x;  
    }  
  
    @Override  
    public int getY() {  
        int y = 0;  
        for (Shape child : shapes) {  
            y = Math.min(y, child.getY());  
        }  
        return y;  
    }  
  
    @Override  
    public double getArea() {  
        double area = 0;  
        for (Shape child : shapes) {  
            area = Math.max(area, child.getArea());  
        }  
        return area;  
    }  
}

使用

Shape circle=new Circle(1,1,1);  
Shape rectangle=new Rectangle(2,2,2,2);  
// 容器中包含圆形和正方形
Shape compoundShape=new CompoundShape(circle,rectangle);  
System.out.println(compoundShape.getArea());

组合模式的优点是符合开闭原则,容易扩展节点,包括叶节点和容器。