Wechat Official Account: Bugstack wormhole stack to get the DDD{domain-driven Design} has a long history, but with the rise of microservices DDD is active in people’s sight, it provides a set of architectural Design ideas, We can use this methodology to design architectures as cohesive, low-coupling, and scalable as possible. This topic is based on THE ACTUAL DDD practice, divided into chapters to design different architecture models. Learning and actual combat is the fastest way into the application level, Hi HelloWorld! I’m coming.

Preface introduces

DDD (Domain-driven Design) was first proposed by Eric Evans. The purpose of DDD is to model the Domain involved in software, so as to deal with the problem of software complexity when the system scale is too large. The whole process goes like this: The development team and domain experts work together to understand and digest domain knowledge through Ubiquitous Language, extract and divide domain knowledge into sub-domains (core sub-domain, common sub-domain, support sub-domain), build models on the sub-domains, and repeat the above steps. This goes back and forth, building a model that fits the current domain.

Development goals

Based on the design idea of domain-driven design, the domain model is established by event storm, the logical and physical boundary of domain is divided reasonably, the domain object and service matrix and service architecture diagram are established, and the code structure model conforming to DDD hierarchical architecture idea is defined to ensure the consistency between business model and code model. Through the above design ideas, methods and processes, guide the team to complete the design and development of microservices according to DDD design ideas. 1. Refuse small monomer, refuse polluting function and service, refuse one-plus function scheduling for a month 2. Construct highly available application service that is easy to meet high-speed Internet iteration 3

Service architecture

  • The application layer {application}

    • Application services are located in the application layer. It represents application and user behavior, is responsible for composing, orchestrating, and forwarding services, and handles the execution sequence of business use cases and the assembly of results.
    • The services of the application layer include application services and domain event related services.
    • Application services can combine and arrange the domain services within the micro-service and the application services outside the micro-service, or directly operate the data such as files and cache at the base layer to form application services and provide coarse-grained services externally.
    • There are two types of domain event services: publishing and subscribing to domain events. Asynchronous data transmission is realized through event bus and message queue to decouple microservices.
  • Domain layer {domain}

    • Domain services are services encapsulated at the domain layer to complete the transformation of operations across entities or value objects in the domain, participating in the implementation process in the same way as entities and value objects.
    • Domain services are exposed as domain services by combining and encapsulating one or more methods of the same entity, or by combining or orchestrating the operations of multiple different entities. Domain services encapsulate the core business logic. The behavior of the entity itself is implemented inside the entity class, encapsulated upward as domain service exposure.
    • To hide the implementation of business logic at the domain layer, all domain methods, services, etc., must be exposed through domain services.
    • To achieve decoupling between aggregations within microservices, cross-aggregation domain service calls and cross-aggregation data correlations are prohibited in principle.
  • Base layer {infrastructrue}

    • Basic services are located in the base layer. Resource services (such as database and cache) are provided for each layer to decouple each layer and reduce the impact of external resource changes on business logic.
    • Basic services are mainly warehouse services, which provide basic resource services for each layer in the way of dependency inversion. Domain services and application services invoke warehouse service interfaces, and implement persistent data objects or direct access to basic resources by warehousing.
  • The interface layer {interfaces}

    • Interface services are located at the user interface layer and are used to process Restful requests sent by users and parse configuration files entered by users, and transmit the information to the application layer.

The development environment

2, springboot 2.0.6.RELEASE 3, idea + maven

Code sample

itstack-demo-ddd-01└ ─ ─ the SRC ├ ─ ─ the main │ ├ ─ ─ Java │ │ └ ─ ─ org. Itstack. The demo │ │ ├ ─ ─ application │ │ │ ├ ─ ─ event │ │ │ │ └ ─ ─ ApplicationRunner. Java │ │ │ └ ─ ─ service │ │ │ └ ─ ─ UserService. Java │ │ ├ ─ ─ domain │ │ │ ├ ─ ─ model │ │ │ │ ├ ─ ─ │ ├─ ├─ ├─ there's no law on your body. There's no law on your body. There's no law on your body ├ ─ ─ the repository │ │ │ │ └ ─ ─ IuserRepository. Java │ │ │ └ ─ ─ service │ │ │ └ ─ ─ UserServiceImpl. Java │ │ ├ ─ ─ proceeds │ │ │ ├ ─ ─ dao │ │ │ │ ├ ─ ─ impl │ │ │ │ │ └ ─ ─ UserDaoImpl. Java │ │ │ │ └ ─ ─ UserDao. Java │ │ │ ├ ─ ─ Po │ │ │ │ └ ─ ─ UserEntity. Java │ │ │ ├ ─ ─ the repository │ │ │ │ ├ ─ ─ mysql │ │ │ │ │ └ ─ ─ UserMysqlRepository. Java │ │ │ │ ├ ─ ─ redis │ │ │ │ │ └ ─ ─ UserRedisRepository. Java │ │ │ │ └ ─ ─ UserRepository. Java │ │ │ └ ─ ─ util │ │ │ └ ─ ─ RdisUtil. Java │ │ ├ ─ ─ interfaces │ │ │ ├ ─ ─ dto │ │ │ │ └ ─ ─ UserInfoDto. Java │ │ │ └ ─ ─ the facade │ │ │ └ ─ ─ DDDController. Java │ │ └ ─ ─ DDDApplication. Java │ ├ ─ ─ resources │ │ └ ─ ─ application. Yml │ └ ─ ─ webapp │ └ ─ ─ WEB - INF │ └ ─ ─ index. The JSP └ ─ ─ the test └ ─ ─ Java └ ─ ─ Org. Itstack. Demo. Test └ ─ ─ ApiTest. JavaCopy the code

Demo part key code block, complete code download concern public number; Bugstack wormhole stack reply | DDD fall to the ground

Application/UserService. Java | application layer service users, service domain specific implementation

/ * * * * wormhole stack application layer user service: https://bugstack.cn * public: bugstack wormhole stack | welcome attention and get more project cases source * Create by fuzhengwei on @ 2019 * /
public interface UserService {

    UserRichInfo queryUserInfoById(Long id);

}
Copy the code

Domain/repository/IuserRepository. Java | domain layer repository, the base layer

/ * * * wormhole stack: https://bugstack.cn * public: bugstack wormhole stack | welcome attention and get more project cases source * Create by fuzhengwei on @ 2019 * /
public interface IUserRepository {

    void save(UserEntity userEntity);

    UserEntity query(Long id);

}
Copy the code

Domain/service/UserServiceImpl Java implementation classes | application layer, application layer is very thin layer can only do the service choreography

/ * * * wormhole stack: https://bugstack.cn * public: bugstack wormhole stack | welcome attention and get more project cases source * Create by fuzhengwei on @ 2019 * /
@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource(name = "userRepository")
    private IUserRepository userRepository;

    @Override
    public UserRichInfo queryUserInfoById(Long id) {
        
        // Query the resource library
        UserEntity userEntity = userRepository.query(id);

        UserInfo userInfo = new UserInfo();
        userInfo.setName(userEntity.getName());

        // TODO query school information, external interface
        UserSchool userSchool_01 = new UserSchool();
        userSchool_01.setSchoolName("Zhenhua Senior Experimental Middle School");

        UserSchool userSchool_02 = new UserSchool();
        userSchool_02.setSchoolName("Northeast Dianli University");

        List<UserSchool> userSchoolList = new ArrayList<>();
        userSchoolList.add(userSchool_01);
        userSchoolList.add(userSchool_02);

        UserRichInfo userRichInfo = new UserRichInfo();
        userRichInfo.setUserInfo(userInfo);
        userRichInfo.setUserSchoolList(userSchoolList);

        returnuserRichInfo; }}Copy the code

Infrastructure/Po/UserEntity. Java | database object classes

/** * database entity object; User entity * wormhole stack: https://bugstack.cn * public: bugstack wormhole stack | welcome attention and get more project cases source * Create by fuzhengwei on @ 2019 * /
public class UserEntity {

    private Long id;
    private String name;

    get/set ...
}
Copy the code

Infrastructrue/repository/UserRepository. Java | domain layer defines the interface, the base layer repository implementation

/ * * * wormhole stack: https://bugstack.cn * public: bugstack wormhole stack | welcome attention and get more project cases source * Create by fuzhengwei on @ 2019 * /
@Repository("userRepository")
public class UserRepository implements IUserRepository {

    @Resource(name = "userMysqlRepository")
    private IUserRepository userMysqlRepository;

    @Resource(name = "userRedisRepository")
    private IUserRepository userRedisRepository;

    @Override
    public void save(UserEntity userEntity) {
        // Save to DB
        userMysqlRepository.save(userEntity);

        // Save to Redis
        userRedisRepository.save(userEntity);
    }

    @Override
    public UserEntity query(Long id) {

        UserEntity userEntityRedis = userRedisRepository.query(id);
        if (null! = userEntityRedis)return userEntityRedis;

        UserEntity userEntityMysql = userMysqlRepository.query(id);
        if (null! = userEntityMysql){// Save to Redis
            userRedisRepository.save(userEntityMysql);
            return userEntityMysql;
        }

        // Query is NULL
        return null; }}Copy the code

Java interfaces/dto UserInfoDto. | dto object class, isolate the database class

/ * * * wormhole stack: https://bugstack.cn * public: bugstack wormhole stack | welcome attention and get more project cases source * Create by fuzhengwei on @ 2019 * /
public class UserInfoDto {

    private Long id;        // ID

    public Long getId(a) {
        return id;
    }

    public void setId(Long id) {
        this.id = id; }}Copy the code

Java interfaces/facade/DDDController. | facade interface

/ * * * wormhole stack: https://bugstack.cn * public: bugstack wormhole stack | welcome attention and get more project cases source * Create by fuzhengwei on @ 2019 * /
@Controller
public class DDDController {

    @Resource(name = "userService")
    private UserService userService;

    @RequestMapping("/index")
    public String index(Model model) {
        return "index";
    }

    @RequestMapping("/api/user/queryUserInfo")
    @ResponseBody
    public ResponseEntity queryUserInfo(@RequestBody UserInfoDto request) {
        return newResponseEntity<>(userService.queryUserInfoById(request.getId()), HttpStatus.OK); }}Copy the code

In summary

  • The above structure is based on a basic introduction to DDD, and the actual development can be adjusted according to this pattern.
  • Currently, the architectural layers are not well separated, and references to hierarchical relationships are not conducive to extension.
  • In the future, the RPC framework will continue to be improved and can be combined to build, so that the whole framework is more conducive to Internet development.