zoukankan      html  css  js  c++  java
  • 17-面向对象之语法(2)

    10. 设计模式:

    1. _new_()的作用:

    • 真正构造一个instance并return,如果不return,那么就没有instance

    • 系统默认隐式地调用这两个魔术方法,当然,自己也可以重写,以及显式调用

      class Animal(object):
      def init():
      print("我是Animal的init,没有得到instance ")
      def new(cls): #因为没有return 一个instance,所以上面的init就不会被调用
      print("我是Animal的new,没有创造instance,也没有return出去instance ")
      a = Animal()
      print(' ')

      class Temp(object):
      def init(self):
      print("我是Temp的init ")
      def new(cls):
      print("我是Temp的new ")
      return super().new(cls) #调用父类的new,构造一个对象

      class People(object):
      def init(self): #当前这个self默认接收了new方法return的instance,并对这个instance做init
      print("我是People的init ")
      def new(cls):
      print("我是People的new,我创造了一个instance并return出去了 ")
      instance = super().new(cls) #调用父类的new,构造一个对象, 隶属于People
      #instance = Temp() #调用其他类产生一个instance,隶属于Temp,但没法调用people的init;

            return instance                 #把这个instance返回出去
      

      p = People()
      print(p,' ')

    2. 单例模式

    某个class创建实例的开销极大,而且一个对象足够使用,就用单例模式

    • 实现一:通过调用类方法返回一个instance,每次想得到一个新的instance都这样操作

      class User(object):
      __instance=None

        def __init__(self,name):
            self.name=name
            
        @classmethod #类方法
        def get_instance(cls,name): #由上面的init说明这里要构造一个形参为name
            if not cls.__instance:  #如果__instance 为None
                cls.__instance = User(name) #之后就去__init__()把当前这个instance的name设置好
            return cls.__instance #确保只构造了一个instance,并且这个instance的name已经设置好
      

      u1 = User.get_instance("zs") #调用类方法来获得instance,而不是一般的new一个instance
      u2 = User.get_instance("ls")

      u3=User("ww")

      print(u1==u2)

      ==判断表达式如果返回True,这两个对象是一个对象,并且内存地址相同

      print(u1.name, u2.name) #分析代码过程,打印的是'zs'

      print("u1对象的内存地址:%s,u2对象的内存地址:%s"%(id(u1),id(u2)))

    • 实现二:确保_new_()只返回一个instance,所以只制造了一个instance

      class User(object):

        __instance=None #私有的类属性
        
        def __init__(self,name):
            self.name=name
      
        def __new__(cls,name):
            if not cls.__instance:  #保证 __new__()返回的instance为恒定值,故而只有一个对象
                cls.__instance = super().__new__(cls)
            return cls.__instance
      

      u1 = User("zs")
      u2 = User("ls")
      print(u1.name,u2.name)
      print(u1==u2)

      ==判断表达式如果返回True,这两个对象是一个对象,并且内存地址相同

      print("u1对象的内存地址:%s,u2对象的内存地址:%s"%(id(u1),id(u2)))

      跟踪创建并初始化对象的过程:new(), init(), str(),

      u1 = User("zs")它先执行

      new的结果记为 I, 即 u1 == I

      init的结果就是 I.name = 'zs',或者说 u1.name = 'zs'

      此时还没有print(u1.name),所以不会激发str

      继续执行u2 = User("ls")

      new的结果也是: u2 == I, 那么此时 u2 == u1,进而u2.name == u1.name == 'zs'

      init的结果是 I.name = 'ls', 所以进而 u2.name = u1.name == I.name = 'ls'

      此时还没有print,所以str依旧没有激发,但是此刻 u1.name == u2.name == I.name = 'ls'

      继续执行 print(u1.name,u2.name),激发了str, 故而打印 u1.name == u2.name == I.name = 'ls'

    3. 工厂模式

    • 帮助我们创建类的实例的一种方式,比直接new一个对象复杂
    • 但使系统的可维护性(后期代码的修改量尽可能小)和可扩展性更强
    • 当两个类的依赖关系已经存在的情况下,我们绝不可能干掉依赖关系。
      借助工厂模式,能让这种依赖关系的可维护性和可扩展性更强:找一个第三方(两个class中间插入接口,借助接口对话)

    以一个“人使用斧头为例”,引入工厂之后:
    人不需要自己new斧头,而是调用工厂,从工厂得到斧头
    而工厂内部就实现了创造不同类型斧头的工作
    这样人和斧头就有了工厂这个接口,以后人的class里面就不会具体涉及斧头class

    • 原始的做法:

      class Person(object):
      def init(self,name):
      self.name=name

        def work(self, axe_type): #人要传入斧头类型
            print(self.name+"开始工作了")
            #person完成work,需要使用一把斧头
      
            #在原始社会,人需要一把石
            #axe = StoneAxe("花岗岩斧头")
            #使用钢铁的斧
            axe = SteelAxe("加爵斧头")
            
            axe.cut_tree()
      

      class Axe(object):
      def init(self,name):
      self.name=name

        def cut_tree(self):
            print("%s斧头开始砍树"%self.name)
      

      class StoneAxe(Axe):
      def cut_tree(self):
      print("使用石头做的斧头砍树")

      class SteelAxe(Axe):
      def cut_tree(self):
      print("使用钢铁做的斧头砍树")

      p = Person("zs")

      p.work("Steel")

      p.work("Stone")

    • 简单工厂(工厂模式的简化版,使用了类的静态方法创建各种实例)

      class Person(object):
      def init(self,name):
      self.name=name

      def work(self, axe_type): #人要传入斧头类型
      print(self.name+"开始工作了")
      #person完成work,需要使用一把斧头

        #已经有工厂,person去找工厂生成一把斧头
        axe =Factory.create_axe(axe_type)
        axe.cut_tree()
      

      class Axe(object):
      def init(self,name):
      self.name=name

        def cut_tree(self):
            print("%s斧头开始砍树"%self.name)
      

      class StoneAxe(Axe):
      def cut_tree(self):
      print("使用石头做的斧头砍树")

      class SteelAxe(Axe):
      def cut_tree(self):
      print("使用钢铁做的斧头砍树")

      工厂类

      class Factory(object):
      #生产斧头,根据用户指定的类型来生产
      @staticmethod #支持在class外部,直接用类名调用
      def create_axe(axe_type):
      if (axe_type == 'Stone'):
      return StoneAxe("花岗岩斧头")
      elif (axe_type == 'Steel'):
      return SteelAxe("钢铁斧头")

      p = Person("zs")

      p.work("Steel")

      p.work("Stone")

    • 工厂模式(使用基本工厂的子类——各种具体工厂类,来分担SinpleFactory的静态方法创建各种实例的工作,更加抽象和更具有可维护性)

      class Person(object):
      def init(self,name):
      self.name=name

        def work(self):
            print(self.name+"开始工作了")
            #person完成work,需要使用一把斧头
      
            #已经有工厂,person去找工厂生成一把斧头
            factory = Steel_Axe_Factory() #即根据Person需求请求具体的工厂{具体工厂继承自基类工厂}
            #factory = Steel_Axe_Factory()
            axe =factory.create_axe()
            axe.cut_tree()
      

      class Axe(object):
      def init(self,name):
      self.name=name

        def cut_tree(self):
            print("%s斧头开始砍树"%self.name)
      

      class StoneAxe(Axe):
      def cut_tree(self):
      print("使用石头做的斧头砍树")

      class SteelAxe(Axe):
      def cut_tree(self):
      print("使用钢铁做的斧头砍树")

      工厂类

      class Factory(object):
      #生产斧头,根据用户指定的类型来生产
      def create_axe(self):
      pass

      class Stone_Axe_Factory(Factory):
      def create_axe(self):
      return StoneAxe("花岗岩斧头")

      class Steel_Axe_Factory(Factory):
      def create_axe(self):
      return SteelAxe("钢铁斧头")

      p = Person("zs")
      p.work() #如果需要改需求,去work()里面改换一个具体工厂即可,当然继续优化

  • 相关阅读:
    Reverse Bits
    Jump Game
    Valid Palindrome
    【计算几何初步-线段相交】【HDU1089】线段交点
    【数位DP】【HDU2089】不要62
    【二分图最大匹配】【HDU2063】过山车
    【分割平面,分割空间类题】【HDU1290 HDU2050】
    【特殊的图+DP】【11月校赛】大家一起玩游戏
    【考虑周全+数学变形】【11月赛】Is it a fantastic matrix?
    【进制问题】【HDU2056】A + B Again
  • 原文地址:https://www.cnblogs.com/LS1314/p/8504454.html
Copyright © 2011-2022 走看看