zoukankan      html  css  js  c++  java
  • Python设计模式

    一.简单工厂模式

    首先来看下工厂模式的原理图:

    模式特点:工厂根据条件产生不同功能的类。

    程序实例:四则运算计算器,根据用户的输入产生相应的运算类,用这个运算类处理具体的运算。

    代码特点:C/C++中的switch...case...分支使用字典的方式代替。

         使用异常机制对除数为0的情况进行处理。

    Python实现代码如下:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    
    class Operation:
        def GetResult(self):
            pass
    
    class OperationAdd(Operation):
        def GetResult(self):
            return self.op1 + self.op2
    
    
    class OperationSub(Operation):
        def GetResult(self):
            return self.op1 - self.op2
    
    
    class OperationMul(Operation):
        def GetResult(self):
            return self.op1 * self.op2
    
    
    class OperationDiv(Operation):
        def GetResult(self):
            try:
                result = self.op1/self.op2
                return result
            except:
                print("error:divided by zero.")
                return 0
    
    class OperationUndef(Operation):
        def GetResult(self):
            print("Undefine operation.")
            return 0
    
    class OperationFactory:
        operation = {}
        operation["+"] = OperationAdd();
        operation["-"] = OperationSub();
        operation["*"] = OperationMul();
        operation["/"] = OperationDiv();
        def createOperation(self,ch):
            if ch in self.operation:
                op = self.operation[ch]
            else:
                op = OperationUndef()
            return op
    
    if __name__ == "__main__":
        op = input("operator: ")
        opa = input("a: ")
        opb = input("b: ")
        factory = OperationFactory()
        cal = factory.createOperation(op)
        cal.op1 = int(opa)
        cal.op2 = int(opb)
        print(cal.GetResult())
    简单工程模式

    二.单例模式

    原理图:

    模式特点:保证类仅有一个实例,并提供一个访问它的全局访问点。

    说明:     为了实现单例模式费了不少工夫,后来查到一篇博文对此有很详细的介绍,而且实现方式也很丰富,通过对代码的学习可以了解更多Python的用法。

    我要问的是,Python真的需要单例模式吗?我指像其他编程语言中的单例模式。

    答案是:不需要!

    因为,Python有模块(module),最pythonic的单例典范。

    模块在在一个应用程序中只有一份,它本身就是单例的,将你所需要的属性和方法,直接暴露在模块中变成模块的全局变量和方法即可!

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    #-*- encoding=utf-8 -*-
    print('----------------------方法1--------------------------')
    #方法1,实现__new__方法
    #并在将一个类的实例绑定到类变量_instance上,
    #如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回
    #如果cls._instance不为None,直接返回cls._instance
    class Singleton(object):
        def __new__(cls, *args, **kw):
            if not hasattr(cls, '_instance'):
                orig = super(Singleton, cls)
                cls._instance = orig.__new__(cls, *args, **kw)
            return cls._instance
    
    class MyClass(Singleton):
        a = 1
    
    one = MyClass()
    two = MyClass()
    
    two.a = 3
    print(one.a)
    #3
    #one和two完全相同,可以用id(), ==, is检测
    print(id(one))
    #29097904
    print(id(two))
    #29097904
    print(one == two)
    #True
    print(one is two)
    #True
    
    print('----------------------方法2--------------------------')
    #方法2,共享属性;所谓单例就是所有引用(实例、对象)拥有相同的状态(属性)和行为(方法)
    #同一个类的所有实例天然拥有相同的行为(方法),
    #只需要保证同一个类的所有实例具有相同的状态(属性)即可
    #所有实例共享属性的最简单最直接的方法就是__dict__属性指向(引用)同一个字典(dict)
    #可参看:http://code.activestate.com/recipes/66531/
    class Borg(object):
        _state = {}
        def __new__(cls, *args, **kw):
            ob = super(Borg, cls).__new__(cls, *args, **kw)
            ob.__dict__ = cls._state
            return ob
    
    class MyClass2(Borg):
        a = 1
    
    one = MyClass2()
    two = MyClass2()
    
    #one和two是两个不同的对象,id, ==, is对比结果可看出
    two.a = 3
    print(one.a)
    #3
    print(id(one))
    #28873680
    print(id(two))
    #28873712
    print(one == two)
    #False
    print(one is two)
    #False
    #但是one和two具有相同的(同一个__dict__属性),见:
    print(id(one.__dict__))
    #30104000
    print(id(two.__dict__))
    #30104000
    
    print('----------------------方法3--------------------------')
    ##通过类的静态字段构造类
    class CP:
        __instance = None
        def __init__(self):
            self.ip = "1.1.1.1"
            self.port = 3306
            self.pwd = "123123"
            self.user = "xxx"
            self.conn_list = [1,2,3,4,5,6]
        @staticmethod
        def get_instance():
            if CP.__instance:
                return CP.__instance
            else:
                # 创建一个对象,并将对象赋值给静态字段__instance
                CP.__instance = CP() #执行init方且创建对象,并赋值给私有静态字段
                return CP.__instance #将赋值的返回给私有静态字段
    
    obj1 = CP.get_instance() # 静态字段类调用
    print(obj1)
    
    print('----------------------方法4--------------------------')
    #方法4:也是方法1的升级(高级)版本,
    #使用装饰器(decorator),
    #这是一种更pythonic,更elegant的方法,
    #单例类本身根本不知道自己是单例的,因为他本身(自己的代码)并不是单例的
    def singleton(cls, *args, **kw):
        instances = {}
        def _singleton():
            if cls not in instances:
                instances[cls] = cls(*args, **kw)
            return instances[cls]
        return _singleton
    
    @singleton
    class MyClass4(object):
        a = 1
        def __init__(self, x=0):
            self.x = x
    
    one = MyClass4()
    two = MyClass4()
    
    two.a = 3
    print(one.a)
    #3
    print(id(one))
    #29660784
    print(id(two))
    #29660784
    print(one == two)
    #True
    print(one is two)
    #True
    one.x = 1
    print(one.x)
    #1
    print(two.x)
    #1
    单例模式

    三.策略模式 

    原理图:

    模式特点:定义算法家族并且分别封装,它们之间可以相互替换而不影响客户端。

    程序实例:商场收银软件,需要根据不同的销售策略方式进行收费

    代码特点:不同于同例1,这里使用字典是为了避免关键字不在字典导致bug的陷阱。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    
    class CashSuper:
        def AcceptCash(self,money):
            return 0
    
    class CashNormal(CashSuper):
        def AcceptCash(self,money):
            return money
    
    class CashRebate(CashSuper):
        discount = 0
        def __init__(self,ds):
            self.discount = ds
        def AcceptCash(self,money):
            return money * self.discount
    
    class CashReturn(CashSuper):
        total = 0;
        ret = 0;
        def __init__(self,t,r):
            self.total = t
            self.ret = r
        def AcceptCash(self,money):
            if (money>=self.total):
                return money - self.ret
            else:
                return money
    
    class CashContext:
        def __init__(self,csuper):
            self.cs = csuper
        def GetResult(self,money):
            return self.cs.AcceptCash(money)
    
    if __name__ == "__main__":
        money = input("money:")
        strategy = {}
        strategy['1'] = CashContext(CashNormal())
        strategy['2'] = CashContext(CashRebate(0.8))
        strategy['3'] = CashContext(CashReturn(300,100))
        ctype = input("type:[1]for normal,[2]for 80% discount [3]for 300 -100.")
        print()
        print(strategy.keys())
        if ctype in strategy.keys():
            cc = strategy[ctype]
        else:
            print("Undefine type.Use normal mode.")
            cc = strategy[1]
        print("you will pay:%d" %(cc.GetResult(int(money))))
    策略模式

    四.装饰模式

    原理图:

    模式特点:动态地为对象增加额外的职责

    程序实例:展示一个人一件一件穿衣服的过程。

    代码特点:无

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    
    class Person:
        def __init__(self,tname):
            self.name = tname
        def Show(self):
           print("dressed %s" %(self.name))
    
    class Finery(Person):
        componet = None
        def __init__(self):
            pass
        def Decorate(self,ct):
            self.componet = ct
        def Show(self):
            if(self.componet!=None):
                self.componet.Show()
    
    class TShirts(Finery):
        def __init__(self):
            pass
        def Show(self):
            print("Big T-shirt ")
            self.componet.Show()
    
    class BigTrouser(Finery):
        def __init__(self):
            pass
        def Show(self):
            print("Big Trouser ")
            self.componet.Show()
    
    if __name__ == "__main__":
        p = Person("somebody")
        bt = BigTrouser()
        ts = TShirts()
        bt.Decorate(p)
        ts.Decorate(bt)
        ts.Show()
    装饰模式

     四、代理模式

    原理图:

    模式特点:为其他对象提供一种代理以控制对这个对象的访问。

    程序实例:同模式特点描述。

    代码特点:无

    class Interface :
        def Request(self):
        return 0
    
    class RealSubject(Interface): 
        def Request(self):
            print "Real request."
    
    class Proxy(Interface):
        def Request(self):
            self.real = RealSubject()
            self.real.Request()
    
    if __name__ == "__main__":
        p = Proxy()
        p.Request()
    proxy

    五、工厂方法模式

    原理图:

    模式特点:定义一个用于创建对象的接口,让子类决定实例化哪一个类。这使得一个类的实例化延迟到其子类。

    程序实例:基类雷锋类,派生出学生类和志愿者类,由这两种子类完成“学雷锋”工作。子类的创建由雷锋工厂的对应的子类完成。

    代码特点:无

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    
    class LeiFeng:
        def Sweep(self):
            print("LeiFeng sweep")
    
    class Student(LeiFeng):
        def Sweep(self):
            print("Student sweep")
    
    class Volenter(LeiFeng):
        def Sweep(self):
            print("Volenter sweep")
    
    class LeiFengFactory:
        def CreateLeiFeng(self):
            temp = LeiFeng()
            return temp
    
    class StudentFactory(LeiFengFactory):
        def CreateLeiFeng(self):
            temp = Student()
            return temp
    
    class VolenterFactory(LeiFengFactory):
        def CreateLeiFeng(self):
            temp = Volenter()
            return temp
    
    if __name__ == "__main__":
        sf = StudentFactory()
        s=sf.CreateLeiFeng()
        s.Sweep()
        sdf = VolenterFactory()
        sd=sdf.CreateLeiFeng()
        sd.Sweep()
    Factory

    六、原型模式

    模式特点:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

    程序实例:从简历原型,生成新的简历

    代码特点:简历类Resume提供的Clone()方法其实并不是真正的Clone,只是为已存在对象增加了一次引用。

         Python为对象提供的copy模块中的copy方法和deepcopy方法已经实现了原型模式,但由于例子的层次较浅,二者看不出区别。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    
    import copy
    class WorkExp:
        place=""
        year=0
    
    class Resume:
        name = ''
        age = 0
        def __init__(self,n):
            self.name = n
        def SetAge(self,a):
            self.age = a
        def SetWorkExp(self,p,y):
            self.place = p
            self.year = y
        def Display(self):
            print(self.age)
            print(self.place)
            print(self.year)
        def Clone(self):
        #实际不是“克隆”,只是返回了自身
            return self
    
    if __name__ == "__main__":
        a = Resume("a")
        b = a.Clone()
        c = copy.copy(a)
        d = copy.deepcopy(a)
        a.SetAge(7)
        b.SetAge(12)
        c.SetAge(15)
        d.SetAge(18)
        a.SetWorkExp("PrimarySchool",1996)
        b.SetWorkExp("MidSchool",2001)
        c.SetWorkExp("HighSchool",2004)
        d.SetWorkExp("University",2007)
        a.Display()
        b.Display()
        c.Display()
        d.Display()
        print('a id is %s' %id(a))
        print('b id is %s' %id(b))
        print('c id is %s' %id(c))
        print('d id is %s' %id(d))
    ###运行结果
    """
    12
    MidSchool
    2001
    12
    MidSchool
    2001
    15
    HighSchool
    2004
    18
    University
    2007
    a id is 4323180160
    b id is 4323180160
    c id is 4323180216
    d id is 4323180384
    """
    原型模式

    七、模板方法模式

    原理图:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    
    class TestPaper:
        def TestQuestion1(self):
            print("Test1:A. B. C. D.")
            print("(%s)" %self.Answer1())
    
        def TestQuestion2(self):
            print("Test1:A. B. C. D.")
            print("(%s)" %self.Answer2())
        def Answer1(self):
            return ""
        def Answer2(self):
            return ""
    
    class TestPaperA(TestPaper):
        def Answer1(self):
            return "B"
        def Answer2(self):
            return "C";
    
    class TestPaperB(TestPaper):
        def Answer1(self):
            return "D"
        def Answer2(self):
            return "D";
    
    if __name__ == "__main__":
        s1 = TestPaperA()
        s2 = TestPaperB()
        print("student 1")
        s1.TestQuestion1()
        s1.TestQuestion2()
        print("student 2")
        s2.TestQuestion1()
        s2.TestQuestion2()
    Templte

    八、外观模式

    原理图:

    模式特点:为一组调用提供一致的接口。

    程序实例:接口将几种调用分别组合成为两组,用户通过接口调用其中的一组。

    代码特点:无

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    class SubSystemOne:
        def MethodOne(self):
            print("SubSysOne")
    
    class SubSystemTwo:
        def MethodTwo(self):
            print("SubSysTwo")
    
    class SubSystemThree:
        def MethodThree(self):
            print("SubSysThree")
    
    class SubSystemFour:
        def MethodFour(self):
            print("SubSysFour")
    
    
    class Facade:
        def __init__(self):
            self.one = SubSystemOne()
            self.two = SubSystemTwo()
            self.three = SubSystemThree()
            self.four = SubSystemFour()
        def MethodA(self):
            print("MethodA")
            self.one.MethodOne()
            self.two.MethodTwo()
            self.four.MethodFour()
        def MethodB(self):
            print("MethodB")
            self.two.MethodTwo()
            self.three.MethodThree()
    
    if __name__ == "__main__":
        facade = Facade()
        facade.MethodA()
        facade.MethodB()
    Foreign_interface

    九、建造者模式

    模式特点:将一个复杂对象的构建(Director)与它的表示(Builder)分离,使得同样的构建过程可以创建不同的表示(ConcreteBuilder)。

    程序实例:“画”出一个四肢健全(头身手腿)的小人

    代码特点:无

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    
    class Person:
        def CreateHead(self):
            pass
        def CreateHand(self):
            pass
        def CreateBody(self):
            pass
        def CreateFoot(self):
            pass
    
    class ThinPerson(Person):
        def CreateHead(self):
            print("thin head")
        def CreateHand(self):
            print("thin hand")
        def CreateBody(self):
            print("thin body")
        def CreateFoot(self):
            print("thin foot")
    
    class ThickPerson(Person):
        def CreateHead(self):
            print("thick head")
        def CreateHand(self):
            print("thick hand")
        def CreateBody(self):
            print("thick body")
        def CreateFoot(self):
            print("thick foot")
    
    class Director:
        def __init__(self,temp):
            self.p = temp
        def Create(self):
            self.p.CreateHead()
            self.p.CreateBody()
            self.p.CreateHand()
            self.p.CreateFoot()
    
    if __name__ == "__main__":
        p = ThickPerson()
        d = Director(p)
        d.Create()
    Build_style

    十、观察者模式

    模式特点:定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,当主题对象状态发生变化时会通知所有观察者。

    程序实例:公司里有两种上班时趁老板不在时偷懒的员工:看NBA的和看股票行情的,并且事先让老板秘书当老板出现时通知他们继续做手头上的工作。

    程序特点:无

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    
    class Observer:
        def __init__(self,strname,strsub):
            self.name = strname
            self.sub = strsub
        def Update(self):
            pass
    
    class StockObserver(Observer):
        #no need to rewrite __init__()
        def Update(self):
            print("%s:%s,stop watching Stock and go on work!" %(self.name,self.sub.action))
    
    class NBAObserver(Observer):
        def Update(self):
            print("%s:%s,stop watching NBA and go on work!" %(self.name,self.sub.action))
    
    class SecretaryBase:
        def __init__(self):
            self.observers = []
        def Attach(self,new_observer):
            pass
        def Notify(self):
            pass
    
    class Secretary(SecretaryBase):
        def Attach(self,new_observer):
            self.observers.append(new_observer)
        def Notify(self):
            for p in self.observers:
                p.Update()
    
    if __name__ == "__main__":
        p = Secretary()
        s1 = StockObserver("xh",p)
        s2 = NBAObserver("wyt",p)
        p.Attach(s1);
        p.Attach(s2);
        p.action = "WARNING:BOSS ";
        p.Notify()
    observer_mode

     十一、抽象工厂模式

    原理图:

    模式特点:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的类。

    程序实例:提供对不同的数据库访问的支持。

         IUser和IDepartment是两种不同的抽象产品,它们都有Access和SQL Server这两种不同的实现;IFactory是产生IUser和IDepartment的抽象工厂,根据具体实现(AccessFactory和SqlFactory)产生对应的具体的对象(CAccessUser与CAccessDepartment,或者CSqlUser与CSqlDepartment)。

    代码特点:无

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #  Author: Jason Wang
    
    class IUser:
        def GetUser(self):
            pass
        def InsertUser(self):
            pass
    
    class IDepartment:
        def GetDepartment(self):
            pass
        def InsertDepartment(self):
            pass
    
    class CAccessUser(IUser):
        def GetUser(self):
            print("Access GetUser")
        def InsertUser(self):
            print("Access InsertUser")
    
    
    class CAccessDepartment(IDepartment):
        def GetDepartment(self):
            print("Access GetDepartment")
        def InsertDepartment(self):
            print("Access InsertDepartment")
    
    class CSqlUser(IUser):
        def GetUser(self):
            print("Sql GetUser")
        def InsertUser(self):
            print("Sql InsertUser")
    
    
    class CSqlDepartment(IDepartment):
        def GetDepartment(self):
            print("Sql GetDepartment")
        def InsertDepartment(self):
            print("Sql InsertDepartment")
    
    class IFactory:
        def CreateUser(self):
            pass
        def CreateDepartment(self):
            pass
    
    class AccessFactory(IFactory):
        def CreateUser(self):
            temp=CAccessUser()
            return temp
        def CreateDepartment(self):
            temp = CAccessDepartment()
            return temp
    
    class SqlFactory(IFactory):
        def CreateUser(self):
            temp = CSqlUser()
            return temp
        def CreateDepartment(self):
            temp = CSqlDepartment()
            return temp
    
    if __name__ == "__main__":
        factory = SqlFactory()
        user=factory.CreateUser()
        depart=factory.CreateDepartment()
        user.GetUser()
        depart.GetDepartment()
    
    
    ##
    """
    Sql GetUser
    Sql GetDepartment
    """
    abstract
  • 相关阅读:
    Android 主题theme说明 摘记
    Android开发 去掉标题栏方法 摘记
    安卓项目五子棋代码详解(二)
    关于 ake sure class name exists, is public, and has an empty constructor that is public
    百度地图3.0实现图文并茂的覆盖物
    android onSaveInstanceState()及其配对方法。
    关于集成科大讯飞语音识别的 一个问题总结
    android 关于 webview 控制其它view的显示 以及更改view数据失败的问题总结
    C# 解析 json Newtonsoft果然强大,代码写的真好
    c#数据类型 与sql的对应关系 以及 取值范围
  • 原文地址:https://www.cnblogs.com/jasonwang-2016/p/5987660.html
Copyright © 2011-2022 走看看