要想了解领域驱动模型,首先你要先知道基于领域驱动的架构目录,以下图前端
-
Repository 数据仓库,用于数据访问和持久化(功能是基于业务来作,并在业务里定义接口来约束数据库的操做功能)
-
Model 业务处理
-
建模(模型封装业务须要的数据)
-
接口(约束数据库的访问功能)
-
协调 领域模型 和 数据访问处理业务(调用数据库访问的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层导入上述代码类,并实例对象,调用服务层验证方法就能够了
咱们看到,整个代码设计都是由登录这个业务逻辑驱动的
不过你感受这绕来绕去的,感受没什么好的,能够这么说小型项目,毫无疑问增长不少没必要要的代码,可是对于大型网站,协做与维护是很是方便的,只能因景而异啦
再加个图吧