領域驅動模型

領域驅動模型

 

  要想了解領域驅動模型,首先你要先知道基於領域驅動的架構目錄,以下圖前端

  • Repository  數據倉庫,用於數據訪問和持久化(功能是基於業務來作,並在業務裏定義接口來約束數據庫的操做功能)

  • Model  業務處理

  1. 建模(模型封裝業務須要的數據)

  2. 接口(約束數據庫的訪問功能)

  3. 協調 領域模型  和  數據訪問處理業務(調用數據庫訪問的xx方法,並把處理的數據封裝到模型中),把模型返回給服務層

  • service 服務層(請求有規則,響應有規則)---調用業務處理的協調者的協調方法

  • UI層  負責請求對應的類

 

  領域驅動設計,用本身的話說就是業務邏輯場景驅動整個程序代碼的設計python

  仍是不懂?那看個例子吧,這個例子再尋常不過了mysql

  登錄場景sql

場景分析:數據庫

  • 常見的兩種登錄方法--用戶名+密碼  或  郵箱+密碼,這就是前端提交後臺要處理的數據,三個一塊兒交過去,沒有的就等於None
  • 登錄失敗,要顯示錯誤信息,登錄成功,就要顯示我的信息,因此後臺處理完後要返回這些數據

 

  領域模型,固然是從模型入手了,模型怎麼建了,模型是要封裝全部須要的數據,那咱們須要哪些數據---登錄狀態,錯誤信息,以及我的信息,其中涉及數據庫訪問的就是我的信息了,那麼模型就要封裝我的信息架構

  • 模型---我的信息:id,用戶名,郵箱,最近登錄時間,用戶類型,會員類型(其中用戶類型和會員類型又能夠分出小模型)

因此在Model裏建一個User.pypost

?
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
#創建模型
 
class VipType:
 
     dic = {
         1 : '金牌' ,
         2 : '銀牌' ,
         3 : '銅牌'
     }
 
     def __init__( self ,nid):
         self .nid = nid
 
     @property
     def caption( self ):
         for i in VipType.dic:
             if i = = self .nid:
                 return VipType.dic[i]
 
 
class UserType:
 
     dic = {
         1 : '普通用戶' ,
         2 : '商戶' ,
         3 : '管理員'
     }
 
     def __init__( self ,nid):
         self .nid = nid
 
     @property
     def caption( self ):
         for j in UserType.dic:
             if self .nid = = j:
                 return UserType.dic[j]
 
class User:
 
     def __init__( self ,nid,username,email,last_login,vip_type_obj,user_type_obj):
         self .nid = self .nid
         self .username = username
         self .email = email
         self .last_login = last_login
         self .vip_type = vip_type_obj
         self .user_type = user_type_obj

   除了建模型,還在這裏定義接口(接口主要限制數據庫的訪問功能),分析認證的過程是郵箱或用戶名,能夠分開定義成兩個方法,一個用用戶名驗證的方法,一個就是用郵箱驗證的方法,最後還要有更新用戶登錄時間的方法fetch

?
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
#定義接口
 
class IUserRepository:
 
     def fetch_one_by_username( self ,username,password):
         '''
         經過密碼到數據庫進行驗證
         :param username: 用戶名
         :param password: 密碼
         :return:
         '''
 
     def fetch_one_by_email( self ,email,password):
         '''
         經過郵箱到數據庫進行驗證
         :param email:
         :param password:
         :return:
         '''
 
     def update_last_login_by_nid( self ,nid,cur_date):
         '''
         經過nid更新數據庫的登錄時間
         :param nid: id
         :param cur_date: 最新時間
         :return:
         '''

   好!接口和模型定義好後,就能夠去Repository把接口裏方法實現了網站

  • 數據訪問,數據訪問,確定要要鏈接上數據庫才能訪問

  在Repository建立了一個DbConnection.py,專門用鏈接數據庫的spa

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import pymysql
import Config
 
 
class DbConnection:
 
     def __init__( self ):
         #數據庫的信息寫在配置文件裏
         self .__conn_dict = Config.PY_MYSQL_CONN_DICT
         self .conn = None
         self .cursor = None
 
     #鏈接數據庫,建立遊標
     def connect( self ,cursor = pymysql.cursors.DictCursor):
         self .conn = pymysql.connect( * * self .__conn_dict)
         self .cursor = self .conn.cursor(cursor = cursor)
         return self .cursor
 
     #關閉遊標以及數據庫
     def close( self ):
         self .conn.commit()
         self .cursor.close()
         self .conn.close()

   作好了這一步,訪問數據庫時只要實例化這樣一個對象就能夠了

  針對業務層User創建一個UserRepository.py專門實現User文件接口的方法,並處理獲得的數據封裝到模型裏

?
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
from Model.User import VipType,User,UserType,IUserRepository
#進行數據庫鏈接的另成立模塊
from .DbConnection import DbConnection
 
 
class UserDb(IUserRepository):
 
     def __init__( self ):
         self .conn = DbConnection()
 
     def fetch_one_by_email( self ,email,password):
         ret = None
         cursor = self .conn.connect()
         sql = '''select nid,username,email,last_login,vip_type,user_type
          from UserInfo where email=% and password=%'''
         cursor.execute(sql,(email,password))
         #db_result是一個字典
         db_result = cursor.fetchone()
         self .conn.close()
         if db_result:
             #調用模型進行封裝
             ret = User(nid = db_result[ 'nid' ],
                        username = db_result[ 'username' ],
                        email = db_result[ 'email' ],
                        last_login = db_result[ 'last_login' ],
                        user_type = UserType(nid = db_result[ 'user_type' ]),
                        vip_type = VipType(nid = db_result[ 'vip_type' ]))
             return ret
 
 
 
     def fetch_one_by_username( self ,username,password):
         ret = None
         cursor = self .conn.connect()
         sql = '''select nid,username,email,last_login,vip_type,user_type
          from UserInfo where username=% and password=%'''
         cursor.execute(sql,(username,password))
         #db_result是一個字典
         db_result = cursor.fetchone()
         self .conn.close()
         if db_result:
             #調用模型進行封裝
             ret = User(nid = db_result[ 'nid' ],
                        username = db_result[ 'username' ],
                        email = db_result[ 'email' ],
                        last_login = db_result[ 'last_login' ],
                        user_type = UserType(nid = db_result[ 'user_type' ]),
                        vip_type = VipType(nid = db_result[ 'vip_type' ]))
             return ret
 
     def update_last_login_by_nid( self ,nid,cur_date):
         cursor = self .conn.connect()
         sql = '''update UserInfo set last_login=%s where nid=%s'''
         cursor.execute(sql,(cur_date,nid))
         self .conn.close()

   定義好接口方法後咱們須要再次來到業務層,在Model的User.py寫入協調類,用於調用數據倉庫的方法,並把封裝好的模型對象返回給服務層,在調用方法前,須要須要先實例UserRepository對象,這裏能夠用依賴注入

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#協調者,進行認證
 
class UserService:
 
     def __init__( self ,user_repostiory):
         self .db = user_repostiory
 
     def check_login( self ,user,pwd,ema):
         if user:
             user_model = self .db.fetch_one_by_username(username = user,password = pwd)
         else :
             user_model = self .db.fetch_one_by_email(email = ema,password = pwd)
         if user_model:
             current_date = datetime.datetime.now()
             self .db.update_last_login_by_nid(user_model.nid,current_date)
         return user_model

  那麼對於協調者來講,驗證的數據哪裏來,沒錯就是服務層,不只接收處理數據仍是傳遞客戶輸入的數據進行驗證,而且在服務層裏協調類裏調用業務層的協調方法

   在開始寫服務層時,你必須理解這句話,就是請求有規則,響應有規則---請求就是傳客戶數據,響應就是收業務處理數據,到了服務層就要按服務層的規則,按照服務層定義進行封裝數據

  在服務層下建個User的文件夾專門服務業務層的User

  咱們先定義‘請求規則’--Request.py

?
1
2
3
4
5
6
7
8
9
10
'''
對於request類的創建規則就是,前端發來多少項數據就對應創建幾個字段
'''
 
class UserRequest:
 
     def __init__( self ,usr,pwd,ema):
         self .username = usr
         self .password = pwd
         self .email = ema

   而後咱們定義一下響應規則,在這裏咱們必須清楚,返回給客戶看的是字符串,業務層返回模型裏的字段帶有對象的就到這裏細化

Response.py

?
1
2
3
4
5
6
7
8
9
10
11
'''
須要返回的信息無非就是執行狀態,錯誤信息,以及用戶信息
其中用戶信息又封裝到ModelView對象裏
'''
 
class UserResponse:
 
     def __init__( self ,status = True ,message = '',model_view = None ):
         self .status = status
         self .message = message
         self .modelView = model_view

 ModelView.py

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'''
在服務層,模型數據的接收者,而且細化,在這裏是封裝客戶信息
'''
class UserModelView:
 
     def __init__( self ,nid,username,email,
                  last_login,user_type_id,user_type_caption,
                  vip_type_id,vip_type_caption):
         self .nid = nid
         self .username = username
         self .email = email
         self .last_login = last_login
         self .user_type = user_type_id
         self .user_type_caption = user_type_caption
         self .vip_type = vip_type_id
         self .vip_type_caption = vip_type_caption

   最後剩下就是調用業務層協調者和把數據返回給UI層的服務層協調者了,這裏要調用業務層的協調者就必須實例一個業務層的UserService對象,這個經過參數的形式傳入到服務層協調類的構造方法裏,就又要用到依賴注入了,而且最終的信息要封裝到服務層的規則裏(Response),因此在定義驗證方法裏實例Response對象

?
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
'''
在Service裏,接收request對象裏封裝信息
調用model業務層的方法作驗證,先要實例業務層service對象(寫在構造方法裏)
把驗證的結果信息封裝到response對象裏
'''
 
from Services.User.Response import UserResponse
from Services.User.ModelView import UserModelView
 
class service:
 
     def __init__( self ,model_user_service):
         self .modelUserService = model_user_service  #業務層協調者
 
     def check_login( self ,user_request):
         response = UserResponse()
 
         try :
             model = self .modelUserService.check_login(user = user_request.usr,pwd = user_request.pwd,ema = user_request.ema)
             if model:
                UserModelView(nid = model.nid,
                              username = model.username,
                              email = model.email,
                              last_login = model.last_login,
                              user_type_id = model.user_type.nid,
                              user_type_caption = model.user_type.caption,
                              vip_type_id = model.vip_type.nid,
                              vip_type_caption = model.vip_type.caption)
                response.modelView = UserModelView
             else :
                 raise Exception( '密碼錯誤!' )
 
         except Exception as e:
             response.status = False
             response.message = str (e)
 
         return response

   最後在UI層導入上述代碼類,並實例對象,調用服務層驗證方法就能夠了

 

  咱們看到,整個代碼設計都是由登錄這個業務邏輯驅動的

  不過你感受這繞來繞去的,感受沒什麼好的,能夠這麼說小型項目,毫無疑問增長不少沒必要要的代碼,可是對於大型網站,協做與維護是很是方便的,只能因景而異啦

  再加個圖吧

相關文章
相關標籤/搜索