python:组合模式 ## 原理 组合模式是一种抽象。将整体和部分统一对待。 比如一个网页。它可以显示一条新闻,N条新闻,它的操作“显示”对于一条新闻和N条新闻的动作是一致的。“N条新闻”是“一条新闻”的组合。它们都有相同的方法“显示”。 由部分“组合”成整体,加大了代码复用的灵活性。 ## 实现 下面实现一个内容模版。比如一个网页的内容,可以由不同的元素组合。 ###定义接口 ``` import abc import random # 组合模式 class IJsonTemplateDataTree(object): # 定义一个接口 __metaclass__ = abc.ABCMeta @abc.abstractmethod def add(self, component): pass @abc.abstractmethod def to_json(self): pass ``` ### 定义组件类 组件类是一个List。它实现组件的接口。调用组件的add方法可以把叶子添加到组件中。多个组件也能组合成一个大的组件。 ``` class JsonTemplateDataConponent(IJsonTemplateDataTree): def __init__(self, tp_name): self.comp_list = [] self.data = [] def add(self, component): self.comp_list.append(component) def to_json(self): self.data = [] for item in self.comp_list: self.data.append(item.to_json()) return self.data ``` 值得注意的是,组件只提供“组合”的功能。它的to_json方法,是循环调用的叶子(或子组件)的方法。功能的实现最终下沉到叶子。 ## 叶子节点 组件组合叶子节点,具体的实现由叶子节点控制。在这定义了两个不同的叶子类型(article, gif),它们产生不同的数据。 ``` class JsonTemplateArticleLeaf(IJsonTemplateDataTree): def __init__(self, tp_type, db_type, sub_cate, count): self.tp_type = tp_type self.db_type = db_type self.sub_cate = sub_cate self.count = count def add(self): pass def to_json(self): # 拼点假的数据,实际操作将很复杂 data = [] for i in range(0, self.count): data.append({ 'types': self.tp_type, 'data':{ 'ID': random.randint(0,999), 'Title': 'a article', 'Category': self.sub_cate } }) return data class JsonTemplateGifLeaf(IJsonTemplateDataTree): def __init__(self, tp_type, db_type, sub_cate, count): self.tp_type = tp_type self.db_type = db_type self.sub_cate = sub_cate self.count = count def add(self): pass def to_json(self): # 拼点假的数据,实际操作将很复杂 data = [] for i in range(0, self.count): data.append({ 'types': self.tp_type, 'data':{ 'ID': random.randint(0,999), 'Title': 'a gif', 'Category': self.sub_cate } }) return data ``` ## 调用组件 ``` tp_list = JsonTemplateDataCompent('') # 创建一个组件 tp_list.add(JsonTemplateArticleLeaf('article', 'article', 'lishi', 2)) # 创建一个article叶节点,并添加到组件 tp_list.add(JsonTemplateGifLeaf('img', 'gif', 6, 3)) # 创建一个gif节点,并添加到组件 print(tp_list.to_json()) # 调用组件的to_json方法。它会循环调用所有叶节点的方法。 ``` 来自 大脸猫 写于 2017-12-17 14:02 -- 更新于2020-10-19 13:06 -- 0 条评论