当前位置:网站首页>Chapter 6: implement a persistence adapter
Chapter 6: implement a persistence adapter
2022-07-23 23:37:00 【Hello y】
In the 1 In the chapter , I criticize the traditional layered architecture , And claimed that it supported “ Database based design ”, Because at the end of the day , Everything depends on the persistence layer . In this chapter . We'll see how to make the persistence layer a plug-in to the application layer , To subvert this Dependence
Dependency inversion
Ports are actually an indirect layer between application services and persistence code . Let's remind ourselves , We add this layer of indirection in order to realize that there is no need to consider persistence , This means that there is no code dependency on the persistence layer . Refactoring in persistent code does not necessarily lead to Code changes in the core .
Of course , At run time , We still have a dependency from the application core to the persistence adapter . for example , If we modify the code in the persistence layer and introduce an error , We may still interrupt Functions in the core of the application . however , As long as the port contract is satisfied , We can freely do what we want in the persistence adapter , Without affecting the core .
The responsibility of the persistence adapter
Let's take a look at what persistence adapters usually do :
1、 Accept input
2、 Map input to database format
3、 Send input to the database
4、 Map database output to application format
5、 Return output
The persistence adapter receives input through a port interface . The input model can be a domain entity or an object dedicated to a specific database operation . then , It maps the input model to a format that it can use to modify or query the database . stay Java In the project , We usually use Java persistence API(JPA) Communicating with the database , So we can map Input to reflect the database table structure JPA In the entity object . Depending on the context , Map the input model to JPA Entities may need to do a lot of work , But it's not good , So we will be in the 8 Chapter “ Mapping between boundaries ” Strategies without mapping are discussed in .
We don't have to use it JPA Or other object relationship mapping framework , Instead, use any other technology to talk to the database . We can map the input model into ordinary SQL sentence , And send these statements to the database . Or we can serialize the input data into a file , Then read them from the file, and read them back from there .
The important part is , The input model of the persistence adapter is located at the core of the application ( the application core) in , Not in the persistence adapter itself , Therefore, changes in the persistence adapter will not Influence the core .
Next , The persistence adapter will query the database and receive the query results .
Last , It maps the answers of the database to the output model expected by the port , And back to it . Say it again . It is important to , The output model is located in the application core , Not in the persistence adapter .
In addition to the fact that the input and output models are at the core of the application rather than the persistence adapter itself , The persistence adapter itself , Its responsibilities are no different from the traditional persistence layer .
Slice port interface
The interface isolation principle solves this problem . It points out that , Wide interfaces should be divided into specific interfaces , So that clients only know the methods they need .
Applying the interface isolation principle can eliminate unnecessary dependencies , And make existing dependencies more visible .
Each service now depends only on the methods it actually needs . what's more , The names of these ports clearly illustrate their role . In the test , We no longer need to consider which methods need to be simulated , Because most of the time , There is only one method per port .
Of course ,“ Each port has a method ” The method of may not be applicable to all situations . There may be a set of database operations that are very coherent , Often used together , We may want to expand them in an interface .
Slice persistence adapter
In the above figures , We see a single persistence adapter class , It implements all persistence port . However , There are no rules that prohibit us from creating more than one class , As long as all the persistence Ports are implemented .
for example , We can choose to implement a persistence adapter in each domain class , To do this, we need persistent operations ( or DDD In terms of “ polymerization ”), Pictured 19 Shown .
We may divide the persistence adapter into more classes , for example , When we want to use JPA Or another OR-Mapper Implement several persistent ports , And use ordinary SQL Implement other ports for better performance . We can create one JPA Adapter and a common SQL Adapter , Each adapter implements a subset of persistent ports .
please remember , Our domain code doesn't care which class finally fulfills the contract defined by the persistent port . We are free to do what we think is appropriate in the persistence layer , As long as all ports are implemented .
Use SpringData JPA An example of
What about database transaction processing ?
Transactions should span all writes performed in a use case to the database , So that if one of the operations fails , All these operations can be rolled back .
Because the persistence adapter does not know which other database operations are part of the same use case , Therefore, it cannot decide when to open and close transactions . We must delegate this responsibility to the service that coordinates the invocation of the persistence adapter .
Use Java and Spring The easiest way to achieve this is to add application service classes @Transactional notes , such Spring All public methods will be wrapped in transactions :
If we want our service to remain pure , Don't be @Transactional Defiled by notes , We can use aspect oriented programming ( For example, using AspectJ), To weave transaction boundaries into our code base .
How will this help me build maintainable software ?
Building a persistence adapter as a domain code plug-in can free domain code from persistence details , In this way, we can build a rich domain model .
Use narrow port interfaces , We can flexibly implement a port in this way , Implement another port in this way , Different persistence technologies may even be used , The application will not notice . Our can even turn off the complete persistence layer , As long as the port contract is observed .
边栏推荐
- DGS初识
- [redis] redis installation and client redis cli use (batch operation)
- Wechat applet implements a global event bus by itself
- mysqlbinlog命令介绍(远程拉取binlog日志)
- Mongodb database + graphical tools download, installation and use
- [ssm] joint debugging of front and rear protocols ①
- How to migrate databases in the flask framework
- [array] longest continuous subsequence in nc95 array - difficult
- FreeRTOS personal notes - create / delete dynamic tasks, start scheduler
- y75.第四章 Prometheus大厂监控体系及实战 -- prometheus报警设置(六)
猜你喜欢

bjdctf_2020_babystack

No wonder the application effect of ERP in domestic enterprises is generally not ideal

DGS之Mutations

y75.第四章 Prometheus大厂监控体系及实战 -- prometheus报警设置(六)

一,数字逻辑的化简

A deserialized CTF question sharing

Analysis of mobile semantics and perfect forwarding

Open source embedded sig in the openeuler community. Let's talk about its multi OS hybrid deployment framework

jarvisoj_level2

2、 Digital logic functional unit
随机推荐
Learning MySQL is enough
DGS之N+1选择问题
ret2text
第五章、实现Web适配器
SQL语句实战学习
Everything you need to know about parsing JSON with Jackson
BUUCTF -rip
BGP选路,MPLS
jarvisoj_ level2
A great open source micro community light forum source code
How to migrate databases in the flask framework
Matlab Foundation
【音视频技术】视频质量评价 MSU VQMT & Netflix vmaf
Is Zhongyuan securities reliable? Is it legal? Is it safe to open a stock account?
ciscn_ 2019_ n_ eight
[第五空间2019 决赛]PWN5
ubtun 更新源
Stm32f4 check the frequency of each part of the system
Use boundschecker "suggestions collection"
第七章、测试架构元素