python 抽象類、抽象方法、介面、依賴注入、SOLIP
阿新 • • 發佈:2018-12-01
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
):
|