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   
  • 相关阅读:
    【Java学习笔记】java.lang包学习
    winform的md5加密
    地铁线路图的设计与实现
    asp.net的jQuery 表格展开伸缩
    关于批量数据更新的问题(C#高性能)
    JQuery用户名无刷新验证
    Linq分页
    用jQuery写的好的动态显示本机时间的代码
    asp.net防止页面刷新弹出“需要重新发送您以前提交的信息”
    aspx中的html代码调用CS文件中的方法
  • 原文地址:https://www.cnblogs.com/zcok168/p/10051328.html
Copyright © 2011-2022 走看看