1. 程式人生 > >python 抽象類、抽象方法、介面、依賴注入、SOLIP

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()

  

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中的方法否則就會丟擲異常。

 

引入依賴注入

直譯器解釋類的流程

?
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>

  

?
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #######################依賴注入案例二====================================================   # # 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

  

 

     

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 ):