python:oop范式

oop来说,必然逃不过两个概念:继承与组合。

什么时候使用继承,使用时候组合?

  • 在写简单的代码的时候,谁都清楚该怎么区分。
  • 但是,一旦业务逻辑复杂,就很难确定当前情况该使用继承还是组合了。相信使用过任意oop语言做过实际项目的人都对此深有体会。
  • 就我个人而言,也是经常在业务代码中,很难去判断当前情况该使用哪一种方式。之前我的一位老师说过,代码没有对错,只有好坏。所以,该如何使用,有时候真的只能用一句:“看具体使用场景”来回答了。

  • 这里给出《Learning Python》中的一个使用继承的范式,及一个使用组合的范式。

  • 首先是继承的范式:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @name   : inherit.py
# @author : cat
# @date   : 2017/6/25.

from tools import AttrDisplay


# 继承关系
class Employee(AttrDisplay):
    def __init__(self, name, salary=0):
        self.name = name
        self.salary = salary

    def giveRaise(self, percent):
        self.salary = self.salary + self.salary * percent

    def work(self):
        return "{} does stuff.".format(self.name)


class Chef(Employee):
    def __init__(self, name, ):
        Employee.__init__(self, name, 5000)

    def work(self):
        return "{} make food.".format(self.name)


class Server(Employee):
    def __init__(self, name):
        Employee.__init__(self, name=name, salary=4000)

    def work(self):
        return "{} interfaces with customer.".format(self.name)


class PizzaRobot(Chef):
    def __init__(self, name):
        Chef.__init__(self, name)

    def work(self):
        return "{} make pizza.".format(self.name)


if __name__ == '__main__':
    e = Employee('tom ding')
    c = Chef('victor')
    s = Server('Ann')
    r = PizzaRobot('stone')

    print(e, c, s, r, sep="\n")
    pass
  • 其次是一个组合的范式:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @name   : combination.py
# @author : cat
# @date   : 2017/6/25.
# 组合关系
from tools import AttrDisplay

from inherit import Server, PizzaRobot


class Customer(AttrDisplay):
    def __init__(self, name):
        self.name = name

    def order(self, server):
        print(self.name, "order from", server)

    def pay(self, server):
        print(self.name, "pay item to", server)


class Oven(AttrDisplay):
    def bake(self):
        return "oven bake."


class PizzaShop(AttrDisplay):
    def __init__(self):
        self.chep = PizzaRobot('bob')
        self.server = Server('pat')
        self.oven = Oven()

    def order(self, name):
        customer = Customer(name)
        customer.order(self.server)
        self.server.work()
        self.chep.work()
        self.oven.bake()
        customer.pay(self.server)


if __name__ == '__main__':
    shop = PizzaShop()
    shop.order("tom ding")
    print(".....")
    shop.order("pythonCat")

使用的一个工具类:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @name   : tools.py
# @author : cat
# @date   : 2017/6/25.

class AttrDisplay:
    def __gatherAttrs(self):
        return ["{}={}".format(key, getattr(self, key))
                for key in self.__dict__.keys()]

    def __repr__(self):
        return "<{}:{}>" \
            .format(self.__class__.__name__,
                    ",".join(self.__gatherAttrs()))

    def __str__(self):
        return AttrDisplay.__repr__(self)


if __name__ == '__main__':
    class P(AttrDisplay):
        def __init__(self, name, age):
            self.name = name
            self.age = age

        def func(self):
            return "func ...."


    c = P('tom ding', 32)
    print(c)

上述代码清晰易懂:

  • 在继承的范式中,给出的是一个员工的继承关系。厨师,服务员都是员工的子类,披萨机器人是厨师的子类。
  • 在组合的范式中,披萨店是一个组合类,也是控制器。披萨店里面有烤箱,服务员,厨师,和顾客。其中,除了顾客之外,其他的店里必须存在的,而顾客是流动的,不固定的。

以上的关于oop的继承与组合的范式只是辅助与警醒如何去正确的使用继承与组合。
在实际项目中,复杂的业务逻辑里面,可能会掺杂各种耦合,导致继承不像继承,组合不像组合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值