zoukankan      html  css  js  c++  java
  • python 抽象类、抽象方法、接口、依赖注入、SOLIP

    python 抽象类、抽象方法、接口、依赖注入、SOLIP 

    1、程序设计原则:SOLIP

    SOLIP设计原则
      1、单一责任原则(SRP)
        一个对象对只应该为一个元素负责
      2、开放封闭原则(OCP)
        对扩展开放,修改封闭
      3、里氏替换原则(LSP)
        可以使用任何派生类替换基类
      4、接口分离原则(ISP)
        对于接口进行分类避免一个接口的方法过多
      5、依赖倒置原则(DIP)
        隔离关系,使用接口或抽象类代指
      6、依赖注入(DI)和控制反转原则(ICO)
        使用钩子再原来执行流程中注入其他对象

    接口:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # =================================================以下是接口
    class IorderRepository:  ##接口
        def fetch_one_by(self,nid):
            '''
            获取单条数据的方法,所有的继承呢当前类的类必须继承
            :param nid:
            :return:
            '''
            # raise Exception('子类中必须包含该方法')
     
    class OrderReposititory(IorderRepository): #类
        def fetch_one_by(self,nid):
            print(nid)
    obj = OrderReposititory()
    obj.fetch_one_by(1)

     

    抽象类抽象方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import abc
    class Foo(metaclass=abc.ABCMeta):  ##抽象类
        def f1(self):
            print(123)
     
        def f2(self):
            print(456)
     
        @abc.abstractmethod  ##抽象方法
        def f3(self):
            '''
            ???
            :return:
            '''
     
    class Bar(Foo):
        def f3(self):
            print(33333)
     
    b = Bar()
    b.f3()

    抽象类, 抽象方法:

        抽象类中只能有抽象方法,子类继承抽象类时,不能通过实例化使用其抽象方法,必须实现该方法。py3引入了abc模块

    class Foo(object):
        def exec(self):
            raise NotImplementedError('请实现exec方法')
     
    class A(Foo):
        pass
    obj=A()
    obj.exec()
    
    
    类A继承类Foo,因而拥有类Foo的所有属性。类A实例化一个对象obj,obj调用exec()方法,如果类A自己没有定义exec方法,就会主动抛出异常(raise)。
    from abc import abstractmethod,ABCMeta
     
    class Foo(metaclass=ABCMeta):
        @abcstractmethod
        def exec(self):
            pass
     
    class A(Foo):
        pass
    obj=A()
    
    
    从abc模块调用类abstractmethod和类ABCMeta,自己定义类Foo,继承抽象类ABCMeta,在类Foo中定义exec方法,并添加装饰器abcstractmethod。定义类A继承类Foo,并实例化对象obj,类A中必须有类Foo中的方法否则就会抛出异常。

     组合:

    class SqlHelper:
    
        def fetch_one(self):
            pass
    
        def fetch_all(self):
            pass
    
    class UserInfo:
    
        def __init__(self,helper):
            self.s = helper
    
        def login(self):
            #数据库操作
            self.s.fetch_one()
    
        def logout(self):
            # 数据库操作
            self.s.fetch_one()
    
        def user_list(self):
            # 数据库操作
            self.s.fetch_all()
    
    h = SqlHelper()
    obj = UserInfo(h)
    obj.login()
    #为了降低耦合,使代码减少依赖,将SqlHelper作为参数helper传递进去,两个类之间就没有直接依赖挂关系,叫做组合

    引入依赖注入

    解释器解释类的流程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # ======================================解释器解释类的流程===================
    #  解释器解释:
    # class Foo:
    #     def __init__(self):
    #         self.name =123
    #     def f1(self):
    #         print(self.name)
    # 1.遇到class Foo,执行type的__init__方法
    # 2.type的init的方法做什么呢!不知道
    # obj =Foo()
    # obj.f1()
    # 3.执行Type的__call__方法
    # 执行Foo类的__new__方法
    # 执行Foo类的__init__方法

      

    依赖注入在什么之前做什么操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class MyType(type):
        def __call__(cls, *args, **kwargs):  ##执行Type的__call__方法,这里的cls就是<__main__.Foo object at 0x001B59F0> Foo类
            obj = cls.__new__(cls, *args, **kwargs)  ##Foo的__new__方法
            print('-------------')
            obj.__init__(*args, **kwargs)  ##在执行Foo的__init__的之前做什么操作
            return obj
     
     
    class Foo(metaclass=MyType):
        def __init__(self, name):
            print('============')
            self.name = name
     
        def f1(self):
            print(self.name)
     
     
    obj = Foo(123)
    print(obj)
    print(obj.name)

      

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #=================================依赖注入案例一======================================
    class MyType(type):
        def __call__(cls, *args, **kwargs):  ##执行Type的__call__方法,这里的cls就是<__main__.Foo object at 0x001B59F0> Foo类
            obj = cls.__new__(cls, *args, **kwargs)  ##Foo的__new__方法
            if cls == Foo1:
                obj.__init__(Foo())
            elif cls == Foo2:
                obj.__init__(Foo1())
            return obj
     
     
    class Foo(metaclass=MyType):
        def __init__(self, args):
            print('============')
            self.name = args
     
        def f(self):
            print(self.name)
     
    class Foo1(metaclass=MyType):
        def __init__(self, args):
            print('============')
            self.name = args
     
        def f1(self):
            print(self.name)
     
    class Foo2(metaclass=MyType):
        def __init__(self, args):
            print('============')
            self.name = args
     
        def f2(self):
            print(self.name)
     
     
    obj = Foo2()
    obj.f2()
    # <__main__.Foo1 object at 0x002DA4F0>

    依赖注入案例二:

    class Mapper:
    
        __mapper_relation = {}#私有化
    
        @staticmethod#静态方法
        def register(cls, value):
            Mapper.__mapper_relation[cls] = value#私有字段,类等于值
    
        @staticmethod
        def exist(cls):   ###判断是否在里面
            if cls in Mapper.__mapper_relation:
                return True
            return False
    
        @staticmethod
        def value(cls):
            return Mapper.__mapper_relation[cls]
    
    
    class MyType(type):
        def __call__(cls, *args, **kwargs):  ##执行Type的__call__方法,这里的cls就是<__main__.Foo object at 0x001B59F0> Foo类
            obj = cls.__new__(cls, *args, **kwargs)  ##Foo的__new__方法
            arg_list = list(args)
            if Mapper.exist(cls):
                value = Mapper.value(cls)
                arg_list.append(value)
            obj.__init__(*arg_list, **kwargs)  ##在执行Foo的__init__的之前做什么操作
            return obj
    
    
    class Foo(metaclass=MyType):
        def __init__(self, name):
            self.name = name
    
        def f1(self):
            print(self.name)
    
    
    class Bar(metaclass=MyType):
        def __init__(self, name):
            self.name = name
    
        def f1(self):
            print(self.name)
    
    
    Mapper.register(Foo, '666')
    Mapper.register(Bar, '999')
    obj = Foo()
    
    print(obj)
    print(obj.name)
    b = Bar()
    print(b.name)
    
    # <__main__.Foo object at 0x00583810>
    # 666
    # 999   
  • 相关阅读:
    POJ 1141 括号匹配 DP
    881. Boats to Save People
    870. Advantage Shuffle
    874. Walking Robot Simulation
    文件操作
    861. Score After Flipping Matrix
    860. Lemonade Change
    842. Split Array into Fibonacci Sequence
    765. Couples Holding Hands
    763. Partition Labels
  • 原文地址:https://www.cnblogs.com/zcok168/p/10051328.html
Copyright © 2011-2022 走看看