Python的结构型设计模式之组合模式

组合模式,可用来统合类体系中的两种对象:一种对象能够包含体系中的其他对象,另一种不能。前者叫“组合体”,后者叫“非组合体”
白话来说,好几个东西,都是来自于同一个祖父,但是有些却结合了在一起,而结合在一起的它们,又可以用一个父亲来表示。这个父亲还能继续结合其他的小东西。
今天这个例子确实是很确切了:
大箱子
盒子 铅笔盒 铅笔

铅笔   橡皮   尺子

第一种方法呢,就是:
大箱子:基类A
单个物品(盒子、铅笔、尺子):A的子类
铅笔盒(曰组合体): 继承基类的基类的子类

代码如下,反正我是觉得,这不就是抽象类 + 继承嘛。

class AbstractItem(metaclass=abc.ABCMeta):

    @abc.abstractproperty
    def composite(self):
        pass

    def __iter__(self):
        return iter([])


class SimpleItem(AbstractItem):

    def __init__(self, name, price=0.00):
        self.name = name
        self.price = price

    @property
    def composite(self):
        return False

    def printf(self, indent=""):
        print ("{}${:.2f} {}".format(indent, self.price, self.name))


class AbstractCompositeItem(AbstractItem):

    def __init__(self, *items):
        self.children = []
        if items:
            self.add(*items)

    def add(self, first, *items):
        self.children.append(first)
        if items:
            self.children.extend(items)

    def remove(self, item):
        self.children.remove(item)

    def __iter__(self):
        return iter(self.children)


class CompositeItem(AbstractCompositeItem):

    def __init__(self, name, *items):
        super.__init__(*items)
        self.name = name

    @property
    def composite(self):
        return True

    @property
    def price(self):
        print sum(item.price for item in self)

    def printf(self, indent=""):
        print ("{}${:.2f} {]".format(indent, self.price, self.name))

        for child in self:
            child.printf(indent + "     ")


def main():
    pencil = SimpleItem("Pencil", 0.40)
    ruler = SimpleItem("Ruler", 1.60)
    eraser = SimpleItem("Eraser", 0.20)
    pencilSet = CompositeItem("Pencil Set", pencil, ruler, eraser)
    box = SimpleItem("Box", 1.00)
    boxedPencilSet = CompositeItem("Boxed Pencil Set", box, pencilSet)
    boxedPencilSet.add(pencil)
    for item in (pencil, ruler, eraser, pencilSet, boxedPencilSet):
        item.printf()

而第二种方法呢,我觉得就是在初始化的时做了点小技巧,然后就可以用一个类来全部表示咯

class Item:

    def __init__(self, name, price=0.00, *items):
        self.name = name
        self.price = price
        self.children = []
        if items:
            self.add(*items)

    @classmethod
    def create(Class, name, price):
        return Item(name, price=price)

    @classmethod
    def compose(Class, name, *items):
        return Item(name, *items)

    def composite(self):
        return bool(self.children)

    def add(self, first, *items):
        self.children.extend(itertools.chain((first,), items))

    def remove(self, item):
        self.children.remove(item)

    def __iter__(self):
        return iter(self.children)

    @property
    def price(self):
        return (sum(item.price for item in self) if self.children else self.__price)

    @price.setter
    def price(self, price):
        self.__price = price

    def printf(self, indent=""):
        print ("{}${:.2f} {]".format(indent, self.price, self.name))

        for child in self:
            child.printf(indent + "     ")
就是在初始化的时候给参数加上一个可以存组合体的 [],然后在方法里面加上一个 compose 即可
Item.create("Ruler", 1.60)
Item.compose("Pencil Set", pencil, ruler, eraser)

如果说第一种方法是我们比较常用的,那么第二种模式确实能方便点,不用多创建其他类,只用一个类就可以。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值