python 抽象類、抽象方法、接口、依賴注入、SOLIP

python 抽象類、抽象方法、接口、依賴注入、SOLIP 

 

一、程序設計原則:SOLIP

SOLIP設計原則
  一、單一責任原則(SRP)
    一個對象對只應該爲一個元素負責
  二、開放封閉原則(OCP)
    對擴展開放,修改封閉
  三、里氏替換原則(LSP)
    可使用任何派生類替換基類
  四、接口分離原則(ISP)
    對於接口進行分類避免一個接口的方法過多
  五、依賴倒置原則(DIP)
    隔離關係,使用接口或抽象類代指
  六、依賴注入(DI)和控制反轉原則(ICO)
    使用鉤子再原來執行流程中注入其餘對象python

 

接口:

?
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模塊app

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中的方法不然就會拋出異常。

 組合:post

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傳遞進去,兩個類之間就沒有直接依賴掛關係,叫作組合

 

引入依賴注入

解釋器解釋類的流程fetch

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

依賴注入案例二:spa

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   
相關文章
相關標籤/搜索