python:组合模式

2019-11-21 20:32:44 浏览数 (1)

原理

组合模式是一种抽象。将整体和部分统一对待。 比如一个网页。它可以显示一条新闻,N条新闻,它的操作“显示”对于一条新闻和N条新闻的动作是一致的。“N条新闻”是“一条新闻”的组合。它们都有相同的方法“显示”。 由部分“组合”成整体,加大了代码复用的灵活性。

实现

下面实现一个内容模版。比如一个网页的内容,可以由不同的元素组合。

定义接口

代码语言:javascript复制
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方法可以把叶子添加到组件中。多个组件也能组合成一个大的组件。

代码语言:javascript复制
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),它们产生不同的数据。

代码语言:javascript复制
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

调用组件

代码语言:javascript复制
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方法。它会循环调用所有叶节点的方法。

0 人点赞