意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
何时使用:
1、您想表示对象的部分-整体层次结构(树形结构)。
2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
python代码
from abc import ABCMeta,abstractmethod
class Graphic(metaclass=ABCMeta):
@abstractmethod
def draw(self):
pass
class Point(Graphic):
def __init__(self,p1,p2):
self.x = p1
self.y = p2
def __str__(self):
return f"点({self.x},{self.y})"
def draw(self):
print(str(self))
class Line(Graphic):
def __init__(self,p1,p2):
self.p1 = p1
self.p2 = p2
def __str__(self):
return f"线【{self.p1},{self.p2}】"
def draw(self):
print(str(self))
class Picture(Graphic):
def __init__(self,iterable):
self.children = []
for g in iterable:
self.add(g)
def add(self,graphic):
self.children.append(graphic)
def draw(self):
print(" 复合图形")
for g in self.children:
g.draw()
print("复合图形绘制完")
p1 = Point(2,2)
l1 = Line(Point(10,20),Point(30,40))
l2 = Line(Point(50,60),Point(70,80))
pic1 = Picture([p1,l1,l2])
p1 = Point(6,6)
l1 = Line(Point(11,22),Point(31,41))
l2 = Line(Point(51,66),Point(71,91))
pic2=Picture([p1,l1,l2])
pic3 = Picture([pic1,pic2])
pic3.draw()
E:\source\python\code2pdfword\venv\Scripts\python.exe E:/source/python/code2pdfword/designpattern/dp/composite.py
复合图形
复合图形
点({self.x},2)
线【点({self.x},20),点({self.x},40)】
线【点({self.x},60),点({self.x},80)】
复合图形绘制完
复合图形
点({self.x},6)
线【点({self.x},22),点({self.x},41)】
线【点({self.x},66),点({self.x},91)】
复合图形绘制完
复合图形绘制完
dart 实现
class Employee {
late String name;
late String dept;
late int salary;
late List<Employee> subordinates;
Employee(this.name, this.dept, this.salary) {
subordinates = <Employee>[];
}
void add(Employee e) {
subordinates.add(e);
}
void remove(Employee e) {
subordinates.remove(e);
}
List<Employee> getSubordinates() {
return subordinates;
}
@override
String toString() {
// TODO: implement toString
return 'Employee [ name="$name", dept="$dept", salary="$salary" ]';
}
}
// [Running] dart "e:\source\dart\designpatterns\composite.dart"
// Employee [ name="John", dept="CEO", salary="3000" ]
// Employee [ name="Robert", dept="Head sales", salary="2000" ]
// Employee [ name="Richard", dept="Sales", salary="10000" ]
// Employee [ name="Rob", dept="Sales", salary="10000" ]
// Employee [ name="Michel", dept="Head marketing", salary="2000" ]
// Employee [ name="Laura", dept="Marketing", salary="10000" ]
// Employee [ name="Bob", dept="Marketing", salary="10000" ]