参考书:《大话设计模式》程杰

#简单工厂模式
class Operation: #运算抽象类(接口) python中没有interface概念,可以用class 代替,C++中要用 interface Operation(){} 的方式定义接口
    num1 = 0
    num2 = 0
    def getResult(self):
        raise Exception('未在子类中实现该方法')

class OperationAdd(Operation): #加法运算类
    def getResult(self):
        result = self.num1+self.num2
        return result

class OperationSub(Operation): #减法运算类
    def getResult(self):
        result = self.num1-self.num2
        return result

class OperationMul(Operation): #乘法运算类
    def getResult(self):
        result = self.num1*self.num2
        return result

class OperationDiv(Operation): #除法运算类
    def getResult(self):
        if self.num2 == 0:
            raise Exception('除数不能为0')
        result = self.num1/self.num2
        return result

class SimpleFactory: #简单工厂,主要根据条件生产出相应的运算类对象
    def createOperation(self,operate):
        oper = Operation()
        if operate == '+':
            oper = OperationAdd()
        elif operate == '-':
            oper = OperationSub()
        elif operate == '*':
            oper = OperationMul()
        elif operate == '/':
            oper = OperationDiv()
        return oper

if __name__ == '__main__':
    factory = SimpleFactory()
    oper = factory.createOperation('*') #工厂生产出对象
    oper.num1 = 5
    oper.num2 = 10
    print(oper.getResult())

#工厂方法模式
class Operation: #操作抽象类
    num1 = 0
    num2 = 0
    def getResult(self):
        raise Exception('未在子类中实现该方法')

class OperationAdd(Operation):
    def getResult(self):
        result = self.num1+self.num2
        return result

class OperationSub(Operation):
    def getResult(self):
        result = self.num1-self.num2
        return result

class OperationMul(Operation):
    def getResult(self):
        result = self.num1*self.num2
        return result

class OperationDiv(Operation):
    def getResult(self):
        if self.num2 == 0:
            raise Exception('除数不能为0')
        result = self.num1/self.num2
        return result

class OperationPower(Operation): #新增幂运算
    def getResult(self):
        result = self.num1**self.num2
        return result


#工厂方法模式 把工厂类都定义成了接口(抽象类) 四个运算步骤都在上面定义好了 到时候改都好改,维护好维护
#工厂方法模式 定义一个用于创建对象的接口(IFactory),让子类决定实例化哪一个类
#工厂方法克服了简单工厂模式违背“开放-封闭”原则的缺点,又保持了封装对象创建过程的优点
class IFactory:
    def createOperation(self):
        raise Exception('未在子类实现createOperation方法')

class AddFactory(IFactory): #加法工厂类 工厂类里没有用到运算类Operation
    def createOperation(self):
        return OperationAdd()

class SubFactory(IFactory): #减法工厂类
    def createOperation(self):
        return OperationSub()

class MulFactory(IFactory): #乘法工厂类
    def createOperation(self):
        return OperationMul()

class DivFactory(IFactory): #除法工厂类
    def createOperation(self):
        return OperationDiv()

class PowerFactory(IFactory): #新增幂运算
    def createOperation(self):
        return OperationPower()


if __name__ == '__main__':
    factory = PowerFactory() #加法工厂实例化
    oper = factory.createOperation() #工厂生产出对象
    oper.num1 = 5
    oper.num2 = 3
    print(oper.getResult())

#一个学生信息管理软件的信息如果访问不同的数据库 sqlserver  access mysql 等
#比如软件有学生表user,可以添加学生,获取学生信息 ,用工厂方法来实现,我们只实现插入用户和查询用户

#如果用户可能还要访问mysql 那么可以分别在工厂接口IFactory 和 用户接口IUser 下面泛化一个子类 MysqlUser 和 MysqlFactory
#但是系统中不止有用户表,我后续还要增加一个课程表 course,用来添加课程和获取课程信息的操作呢? 我可能需要增加一个ICourse的接口,
# 然后针对三个数据库 分别实现course的 增删改查操作, 这个好扩展,但是工厂里就要分别在三个工厂里增加 createCourse,违背了开放-封闭原则

class IUser:
    def insertUser(self):raise Exception('子类未实现insertUser')
    def getUser(self):raise Exception('子类未实现getUser')

class SqlserverUser(IUser):
    def insertUser(self):print('sqlserver insert user')
    def getUser(self):print('sqlserver get user')

class AccessUser(IUser):
    def insertUser(self):print('access insert user')
    def getUser(self):print('access get user')


#新增课程接口,然后工厂处还要增加
class ICourse:
    def insertCourse(self): raise Exception('子类未实现insertCourse')
    def getCourse(self): raise Exception('子类未实现getCourse')

class SqlserverCourse(ICourse):
    def insertCourse(self):print('sqlserver insert course')
    def getCourse(self):print('sqlserver get course')

class AccessCourse(ICourse):
    def insertCourse(self):print('access insert course')
    def getCourse(self):print('access get course')





class IFactory:
    def createUser(self):raise Exception('子类未实现createUser')
    def createCourse(self):raise Exception('子类未实现createCourse')

class SqlserverFactory(IFactory): #工厂只是为了获取对象
    def createUser(self):return SqlserverUser()
    def createCourse(self):return SqlserverCourse()

class AccessFactory(IFactory):
    def createUser(self): return AccessUser()
    def createCourse(self):return AccessCourse()



if __name__ == '__main__':
    factory = AccessFactory() #这里可以换成 SqlserverFactory 工厂,切换比较方便
    user = factory.createUser()
    user.insertUser()
    user.getUser()

    course = factory.createCourse()
    course.insertCourse()
    course.getCourse()

#原型模式 Builder
#概念定义:从一个对象再创建一个可定制的对象,而不需要知道任何创建的细节
#适用场景:一般在初始化信息不发生变化的情况下,克隆是最好的办法,既隐藏了对象的创建细节,又对性能大大的提高,不用重新初始化对象,只是动态的获取了对象运行的状态
#在C#中用MemberwiseClone()  在python中 copy
#举例简历的复制
import copy
class IClone:
    def clone(self):return copy.copy(self)

class Resume(IClone):
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age

    def setWorkExperience(self,timeArea,company):
        self.timeArea_work = timeArea
        self.company = company

    def setEducation(self,timeArea,college):
        self.timeArea_education = timeArea
        self.college = college

    def printResume(self):
        print('姓名:',self.name,' 性别:',self.sex,' 年龄:',self.age)
        print(self.timeArea_education,' ',self.college)
        print(self.timeArea_work,' ',self.company)


if __name__ == '__main__':
    r1 = Resume('李二蛋','男',20)
    r1.setEducation('2012-2016','吃饭大学')
    r1.setWorkExperience('2016-2018','种地')
    r1.printResume()

    r2 = r1.clone()
    r2.printResume()

    r3 = r1.clone()
    r3.printResume()

posted on 2020-10-20 17:07  94小渣渣  阅读(82)  评论(0编辑  收藏  举报