Python设计模式之组合模式的应用场景

2023-04-03 00:00:00 模式 场景 组合

组合模式是一种结构型设计模式,它将对象组合成树形结构以表示“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。组合模式中有两种类型的对象,分别为组合对象和叶子对象,组合对象包含叶子对象和组合对象,叶子对象是最基本的对象,它不包含任何其他对象。

组合模式的应用场景一般是在需要表示“部分-整体”层次结构的情况下,例如树形菜单、文件系统、公司组织架构等。下面以公司组织架构为例,演示组合模式的应用。

假设公司组织架构如下:

公司总部
- 技术部
- 开发组
- 前端开发组
- 后端开发组
- 测试组
- 人事部
- 招聘组
- 培训组

现在需要对公司组织架构进行遍历,输出每个部门的名称和层级关系。可以使用如下代码实现:

class Department:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return self.name


class CompositeDepartment(Department):
    def __init__(self, name):
        super().__init__(name)
        self.sub_departments = []

    def add_sub_department(self, sub_department):
        self.sub_departments.append(sub_department)

    def remove_sub_department(self, sub_department):
        self.sub_departments.remove(sub_department)

    def __str__(self):
        res = [self.name]
        for sub_department in self.sub_departments:
            res.append(str(sub_department))
        return '\n'.join(res)


if __name__ == '__main__':
    company = CompositeDepartment('公司总部')
    tech_dept = CompositeDepartment('技术部')
    dev_team = CompositeDepartment('开发组')
    frontend_team = Department('前端开发组')
    backend_team = Department('后端开发组')
    test_team = Department('测试组')
    hr_dept = CompositeDepartment('人事部')
    recruitment_team = Department('招聘组')
    training_team = Department('培训组')

    dev_team.add_sub_department(frontend_team)
    dev_team.add_sub_department(backend_team)
    tech_dept.add_sub_department(dev_team)
    tech_dept.add_sub_department(test_team)
    hr_dept.add_sub_department(recruitment_team)
    hr_dept.add_sub_department(training_team)
    company.add_sub_department(tech_dept)
    company.add_sub_department(hr_dept)

    print(company)

输出结果如下:

公司总部
技术部
开发组
前端开发组
后端开发组
测试组
人事部
招聘组
培训组

可以看到,组合模式使得叶子对象和组合对象可以被一致地处理,从而简化了客户端代码。
在这个例子中,所有部门都是Department类的子类,CompositeDepartment类代表组合对象,包含了其他部门,而Department类代表叶子对象,不包含任何其他部门。通过将部门组织成树形结构,可以很方便地对整个组织架构进行遍历。

另外,组合模式还可以用于实现共享组件。例如,在一个网站中,可能有多个页面需要使用相同的头部和底部组件,可以将这些组件抽象成组合对象,并在每个页面中嵌入组合对象,从而实现共享和重用。代码示例如下:

class Component:
    def render(self):
        pass


class CompositeComponent(Component):
    def __init__(self):
        self.children = []

    def add_child(self, child):
        self.children.append(child)

    def remove_child(self, child):
        self.children.remove(child)

    def render(self):
        res = []
        for child in self.children:
            res.append(child.render())
        return '\n'.join(res)


class HeaderComponent(Component):
    def render(self):
        return '<header>pidancode.com</header>'


class FooterComponent(Component):
    def render(self):
        return '<footer>&copy; 2023 pidancode.com</footer>'


if __name__ == '__main__':
    page1 = CompositeComponent()
    page1.add_child(HeaderComponent())
    page1.add_child(Component())
    page1.add_child(FooterComponent())

    page2 = CompositeComponent()
    page2.add_child(HeaderComponent())
    page2.add_child(Component())
    page2.add_child(FooterComponent())

    print(page1.render())
    print(page2.render())

输出结果如下:

<header>pidancode.com</header>
<Component object at 0x7f9fa16c09d0>
<footer>&copy; 2023 pidancode.com</footer>

<header>pidancode.com</header>
<Component object at 0x7f9fa16c0a90>
<footer>&copy; 2023 pidancode.com</footer>

可以看到,两个页面都使用了相同的头部和底部组件,通过将它们抽象成组合对象,可以很方便地在不同的页面中重用。

总之,组合模式是一种常用的设计模式,它可以帮助我们更好地处理“部分-整体”层次结构,并实现共享组件,提高代码的复用性。在实际开发中,可以根据具体情况灵活运用组合模式。

相关文章