前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python 中的 组合

python 中的 组合

作者头像
公众号---人生代码
发布2020-05-18 16:10:53
6490
发布2020-05-18 16:10:53
举报
文章被收录于专栏:人生代码人生代码

组合是一个面向对象的设计概念,模型a是有关系的。在composition中,一个称为composite的类包含另一个称为component的类的对象。换句话说,一个复合类有另一个类的组件

组合允许复合类重用其包含的组件的实现。复合类不继承组件类的接口,但可以利用其实现

两类之间的构成关系被认为是松散耦合的。这意味着对组件类的更改很少会影响组合类,而对复合类的更改则永远不会影响组件类

这提供了更好的变更适应性,并允许应用程序引入新的要求而不会影响现有代码

当查看两种竞争软件设计时,一种基于继承,另一种基于组成,那么组成解决方案通常是最灵活的。您现在可以查看合成的工作原理

您已经在我们的示例中使用了合成。如果您查看Employee类,则会看到它包含两个属性

代码语言:javascript
复制
# In contacts.py

class Address:
    def __init__(self, street, city, state, zipcode, street2=''):
        self.street = street
        self.street2 = street2
        self.city = city
        self.state = state
        self.zipcode = zipcode

    def __str__(self):
        lines = [self.street]
        if self.street2:
            lines.append(self.street2)
        lines.append(f'{self.city}, {self.state} {self.zipcode}')
        return '\n'.join(lines)

您实现了一个基本地址类,其中包含地址的常用组件。您将street2属性设置为可选,因为并非所有地址都具有该组件

您实现了__str __()来提供地址的漂亮表示。您可以在交互式解释器中看到此实现

代码语言:javascript
复制
from contacts import Address
address = Address('55 Main St.', 'Concord', 'NH', '03301')
print(address)

当您打印address变量时,会调用特殊的方法__str__()。因为您重载了方法来返回一个格式化为地址的字符串,所以您得到了一个很好的、可读的表示。自定义Python类中的操作符和函数重载很好地概述了类中可用的特殊方法,这些方法可用于自定义对象的行为

代码语言:javascript
复制
# In employees.py

class Employee:
    def __init__(self, id, name):
        self.id = id
        self.name = name
        self.address = None

您现在将address属性初始化为None使其成为可选,但是通过这样做,您现在可以将一个Address分配给Employee。还请注意,employee模块中没有对contact模块的引用

复合是一种松散耦合的关系,通常不需要复合类具有组件的知识

# In hr.py

代码语言:javascript
复制
class PayrollSystem:
    def calculate_payroll(self, employees):
        print('Calculating Payroll')
        print('===================')
        for employee in employees:
            print(f'Payroll for: {employee.id} - {employee.name}')
            print(f'- Check amount: {employee.calculate_payroll()}')
            if employee.address:
                print('- Sent to:')
                print(employee.address)
            print('')

您检查以查看雇员对象是否有地址,如果有,则将其打印出来。现在,您可以修改程序以为员工分配一些地址

代码语言:javascript
复制
# In program.py

import hr
import employees
import productivity
import contacts

manager = employees.Manager(1, 'Mary Poppins', 3000)
manager.address = contacts.Address(
    '121 Admin Rd',
    'Concord',
    'NH',
    '03301'
)
secretary = employees.Secretary(2, 'John Smith', 1500)
secretary.address = contacts.Address(
    '67 Paperwork Ave.',
    'Manchester',
    'NH',
    '03101'
)
sales_guy = employees.SalesPerson(3, 'Kevin Bacon', 1000, 250)
factory_worker = employees.FactoryWorker(4, 'Jane Doe', 40, 15)
temporary_secretary = employees.TemporarySecretary(5, 'Robin Williams', 40, 9)
employees = [
    manager,
    secretary,
    sales_guy,
    factory_worker,
    temporary_secretary,
]
productivity_system = productivity.ProductivitySystem()
productivity_system.track(employees, 40)
payroll_system = hr.PayrollSystem()
payroll_system.calculate_payroll(employees)

您向经理和秘书对象添加了两个地址。运行程序时,您将看到打印的地址

代码语言:javascript
复制
$ python program.py

Tracking Employee Productivity
==============================
Mary Poppins: screams and yells for {hours} hours.
John Smith: expends {hours} hours doing office paperwork.
Kevin Bacon: expends {hours} hours on the phone.
Jane Doe: manufactures gadgets for {hours} hours.
Robin Williams: expends {hours} hours doing office paperwork.

Calculating Payroll
===================
Payroll for: 1 - Mary Poppins
- Check amount: 3000
- Sent to:
121 Admin Rd
Concord, NH 03301

Payroll for: 2 - John Smith
- Check amount: 1500
- Sent to:
67 Paperwork Ave.
Manchester, NH 03101

Payroll for: 3 - Kevin Bacon
- Check amount: 1250

Payroll for: 4 - Jane Doe
- Check amount: 600

Payroll for: 5 - Robin Williams
- Check amount: 360

请注意,经理和秘书对象的工资单输出如何显示支票发送的地址

Employee类利用Address类的实现,而不知道Address对象是什么或它是如何表示的。这种类型的设计非常灵活,您可以更改Address类,而不会对Employee类造成任何影响

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CryptoCode 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档