领域驱动模型

领域驱动模型

 

  要想了解领域驱动模型,首先你要先知道基于领域驱动的架构目录,以下图前端

  • 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层导入上述代码类,并实例对象,调用服务层验证方法就能够了

 

  咱们看到,整个代码设计都是由登录这个业务逻辑驱动的

  不过你感受这绕来绕去的,感受没什么好的,能够这么说小型项目,毫无疑问增长不少没必要要的代码,可是对于大型网站,协做与维护是很是方便的,只能因景而异啦

  再加个图吧

相关文章
相关标签/搜索