09、设计模式Python版-组合模式

基本介绍

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。

组合模式依据树形结构来组合对象,用来表示部分以及整体层次。

特点:多个小的构成一个大的,根据不同粒度可以无限制的进行组合

该模式属于结构型模式,它创建了对象组的树形结构。

案例图示

一台计算机由粗看之下由以下配件组成:

  • 机箱(chassis)
  • 显示器(monitor)
  • 核心处理器(CPU)
  • 显卡(GPU)
  • 内存(memory)
  • 硬盘(disk)
  • 电源(mains)
  • 主板(motherboard)

我们可以使用组合模式将这些配件组装到一起,得到一台计算机。

 

优缺点

优点:

  • 高层模块调用简单
  • 节点自由增加

缺点:

  • 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则

代码实现

用Python实现组合模式,需要注意硬盘内存和显示器可能有多个,因此内部需要用列表来进行维护:

# 机箱
class Chassis:
    def __init__(self, brand, model) -> None:
        self.brand = brand
        self.model = model

# 主板
class Motherboard:
    def __init__(self, brand, model) -> None:
        self.brand = brand
        self.model = model

# CPU
class CPU:
    def __init__(self, brand, model) -> None:
        self.brand = brand
        self.model = model

# GPU
class GPU:
    def __init__(self, brand, model) -> None:
        self.brand = brand
        self.model = model

# 内存
class Memory:
    def __init__(self, brand, size) -> None:
        self.brand = brand
        self.size = size

# 硬盘
class Disk:
    def __init__(self, brand, size, type) -> None:
        self.brand = brand
        self.size = size
        self.type = type

# 电源
class Mains:
    def __init__(self, brand, power) -> None:
        self.brand = brand
        self.power = power

# 显示器
class Monitor:
    def __init__(self, brand, size, resolution) -> None:
        self.brand = brand
        self.size = size
        self.resolution = resolution

# 电脑
class Computer:
    def __init__(self) -> None:
        self.chassis = None
        self.monitor = []
        self.cpu = None
        self.gpu = None
        self.memory = []
        self.disk = []
        self.mains = None
        self.motherboard = None

    def add(self, name, obj):
        if hasattr(self, name):
            oldObject = getattr(self, name)
            if isinstance(oldObject, list):
                oldObject.append(obj)
            else:
                setattr(self, name, obj)
        else:
            raise TypeError("invalid accessories")

    def remove(self, name):
        if hasattr(self, name):
            oldObject = getattr(self, name)
            if isinstance(oldObject, list):
                oldObject.pop()
            else:
                setattr(self, name, None)

    def getInfo(self):
        compileMessage = f"""
        ---- compile message ----
        Chassis : {self.chassis.brand} {self.chassis.model}
        Monitor : {list(map(lambda obj:obj.brand + " " + obj.size + " " + obj.resolution, self.monitor))} * {len(self.monitor)}
        CPU : {self.cpu.brand}  {self.cpu.model}
        GPU : {self.gpu.brand}  {self.gpu.model}
        Memory : {list(map(lambda obj:obj.brand + " " + obj.size, self.memory))} * {len(self.memory)}
        Disk : {list(map(lambda obj:obj.brand + " " + obj.size, self.disk))} * {len(self.disk)}
        Mains: {self.mains.brand} {self.mains.power}
        Motherboard : {self.motherboard.brand} {self.motherboard.model}
        """
        return compileMessage
if __name__ == "__main__":
    chassis = Chassis(brand="ROG", model="MINI-ITX")
    monitor = Monitor(brand="SamSung", size="72", resolution="244hz")
    cpu = CPU(brand="Intel", model="core i9-10980XE")
    gpu = GPU(brand="Nvidia", model="RTX3090")
    memory = Memory(brand="SamSung", size="32GB")
    disk = Disk(brand="SamSung", size="2TB", type="SSD")
    mains = Mains(brand="Huntkey", power="700W")
    motherboard = Motherboard(brand="ROG", model="Strix X299-E Gaming II")

    compile = Computer()
    compile.add("chassis", chassis)
    compile.add("monitor", monitor)
    compile.add("cpu", cpu)
    compile.add("gpu", gpu)
    compile.add("memory", memory)
    compile.add("memory", memory)
    compile.add("disk", disk)
    compile.add("mains", mains)
    compile.add("motherboard", motherboard)

    print(compile.getInfo())

# ---- compile message ----
# Chassis : ROG MINI-ITX
# Monitor : ['SamSung 72 244hz'] * 1
# CPU : Intel  core i9-10980XE
# GPU : Nvidia  RTX3090
# Memory : ['SamSung 32GB', 'SamSung 32GB'] * 2
# Disk : ['SamSung 2TB'] * 1
# Mains: Huntkey 700W
# Motherboard : ROG Strix X299-E Gaming II