Due to the development of mobile terminal and the dividend of 2C mode in recent years, the business of some enterprises in tuyere has exploded. From the perspective of architecture, business drives technological change, so the concept of microservices architecture is favored by many enterprises, because it can solve the requirements of high traffic, high concurrency and stability of services.

However, no architectural design can be achieved overnight, and micro services cannot be used from the start. Generally, individual architectures are used to quickly realize requirements and seize the market, and then iteratively expand. You can’t eat a fat man in one sitting.

In recent years, I have experienced the architecture evolution from monomer to microservice, and also directly participated in the project of microservice architecture that has been implemented. I’ve seen good architectural design, and I’ve seen some bad design. Good architectural design, elegant code structure, clear hierarchy, clear demarcation of business boundaries, clear responsibilities of business developers. Bad design can lead to code that is cluttered and difficult to maintain, unable to respond quickly to new requirements, and easy for developers to patch and refactor.

The architect needs to have a comprehensive plan at the business level and for the future of the business, making the architecture highly available, scalable, flexible and easy to use, and hiding its complexity. Good architecture allows the business developers below to “dumb” code according to established patterns.

Since the first step is single architecture, good single architecture design will achieve twice the result with half the effort for our later micro-service separation. Avoid reinventing the wheel and rewriting too much. We can design effectively from these aspects.

Draw business boundaries

If the future architecture has microservices in mind, it is necessary to clarify the business boundary in the single architecture. The common simple division is to distinguish by business, such as: users, goods, orders, payments, permissions, etc. The specific separation degree can be divided according to their own business volume and needs.

The current popular DDD (Domain-driven design) can be used as a guiding principle, but DDD is more theoretical and requires the implementation of good professional ability.

Code hierarchy

After the business is differentiated, it is the design of the project code module. At the code level, we need to follow the MVC pattern and suggest the following code design levels:

├ ─ demo - common │ │ demo - common. On iml │ │ pom. The XML │ │ │ └ ─ SRC │ ├ ─ the main │ │ ├ ─ Java │ │ └ ─ resources │ └ ─test│ └ ─ Java ├ ─ demo - dao │ │ demo - dao. On iml │ │ pom. The XML │ │ │ └ ─ SRC │ ├ ─ the main │ │ ├ ─ Java │ │ └ ─ resources │ └ ─test│ └ ─ Java ├ ─ demo - service │ │ demo - service. On iml │ │ pom. The XML │ │ │ └ ─ SRC │ ├ ─ the main │ │ ├ ─ Java │ │ └ ─ resources │ └ ─test│ │ └ ─ Java └ ─ demo - web demo - web. On iml │ pom. The XML │ └ ─ SRC ├ ─ the main │ ├ ─ Java │ └ ─ resources └ ─test└ ─ JavaCopy the code

It mainly contains four modules

  • Demo-common: Base modules, enumerations, steady on classes, utility classes, configuration classes.
  • Demo-dao: DAO layer, Mapper interface, mapper.xml.
  • Demo-service: indicates the service interface providing layer.
  • Demo-web: Web layer, Controller class, service interface, and external interaction.

The dependency between modules is as follows:

After the project Module is designed, how to design the internal package of each Module? There are usually two partitioning patterns: by business module and then internally by MVC, and by MVC pattern and then internally by business.

1. Partitioning by business modules means that each business module is regarded as a package, and each package has its own MVC, so as to achieve the isolation of business modules.

2. Divide according to MVC pattern, divide different packages, such as Service, serviceImpl, DTO, etc., according to MVC pattern first, and then divide each business’s own model and service interface.

For the above two partitioning modes, individuals choose to divide according to the business model. Such package design has a good matching degree with the later micro-service separation. During the separation, only the code under each business package needs to be copied into the new micro-service, which is easy to migrate and has little change. Each module for different business through package package name, for example: com. Example. Jajian. Service. Order, com. Example. Jajian. Service. The user, etc.

└ ─ SRC ├ ─ the main │ ├ ─ Java │ │ └ ─ com │ │ └ ─ example │ │ └ ─ jajian │ │ ├ ─ common │ │ │ BaserService. Java │ │ │ │ │ └ ─ service │ │ ├ ─ order │ │ │ ├ ─ dto │ │ │ │ OrderDto. Java │ │ │ │ │ │ │ └ ─ service │ │ │ │ OrderService. Java │ │ │ │ │ │ │ └ ─ impl │ │ │ OrderServiceImpl. Java │ │ │ │ │ ├ ─ pay │ │ │ ├ ─ dto │ │ │ │ PayDto. Java │ │ │ │ │ │ │ └ ─ service │ │ │ │ PayService. Java │ │ │ │ │ │ │ └ ─ impl │ │ │ PayServiceImpl. Java │ │ │ │ │ └ ─ user │ │ ├ ─ dto │ │ │ UserDto. Java │ │ │ │ │ └ ─ service │ │ │ │ ├ ─ 0├ ─ sci-imp. Java │ │ ├ ─ sci-imptest└ ─ JavaCopy the code

What good is this division? We developed in this way in the single architecture, and when we need to split into microservices, we can directly split out the business package, because each business package already contains all the associated business classes of the current business.

Avoid associated query for multi-boundary services

Single-table association is simple and easy to use, so multi-table associative query is common in single services. If we do not need to do service splitting later, we do not need to consider this limitation.

However, if there is planning of micro-service in the later stage, if there is no restriction in this aspect in the single service, there will be too many multi-table associated queries in Mapper. XML of Mybatis, which will seriously affect the progress and complexity of service splitting.

If both belong to a business you can use associated query, and the breakup of the micro service belong to different areas of the business should avoid using multiple tables associated query, late because of the different business areas will be quarantined split into different services, namely the database tables are distributed in different servers, is conducted by way of RPC communication between all services, An associated query cannot be processed at this point.

The Controller layer does as little business logic as possible

It is common to see a lot of coders do some business processing in the Controller layer, which I think is very non-standard. Controller layer is the control layer, and the front-end data conversion, here we should only do the request to accept and return, also do not need to do some exception try… catch… Exceptions can be intercepted by the global universal interceptor and then returned to the front-end exception prompt, improving the simplicity of the code.

All parameter validation is also put into the Service layer, because it can also be used to improve code commonality if the service is called internally. Of course, hierarchical domain models are best able to distinguish,

  • DO(Data Object) : This Object corresponds to the database table structure — and transmits Data source objects up through the DAO layer.
  • Date Transfer Object (DTO) : data Transfer Object, which is transmitted by the Service or Manager.
  • VO (View Object) : Objects of the display layer, usually transmitted by the Web to the template rendering engine layer.

The advantage of this separation is that you can be flexible when you need to customize the display layer data for specific purposes, such as user privacy information, ID number desensitization, or user ID encryption display.

Finally, the unified universal return class, through this format encapsulation we will be the data format for global formatting, where the status code can be designed in more detail.

public class CommonResult<T> {

    public static final String CODE_SUCCESS = "0";
    public static final String CODE_FAILED = "9999";

    private String code;
    private T data;

    private String msg;

    private CommonResult(String code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }

    public boolean isSuccess(a) {
        return CODE_SUCCESS.equals(code);
    }

    public static <T> CommonResult<T> success(a) {
        return new CommonResult<>(CODE_SUCCESS, null.null);
    }

    public static <T> CommonResult<T> success(T data) {
        return new CommonResult<>(CODE_SUCCESS, data, null);
    }

    public static <T> CommonResult<T> success(T data, String msg) {
        return new CommonResult<>(CODE_SUCCESS, data, msg);
    }

    public static <T> CommonResult<T> failed(a) {
        return new CommonResult<>(CODE_FAILED, null.null);
    }

    public static <T> CommonResult<T> failed(String errorCode, String msg) {
        return new CommonResult<>(errorCode, null, msg);
    }

    public static <T> CommonResult<T> failed(String msg) {
        return new CommonResult<>(CODE_FAILED, null, msg);
    }

    public static <T> CommonResult<T> failed(T data, String msg) {
        return new CommonResult<>(CODE_FAILED, data, msg);
    }

    public static <T> CommonResult<T> failed(String errorCode, T data, String msg) {
        return new CommonResult<>(errorCode, data, msg);
    }
   
   // omit the setter and getter
}
Copy the code

Afterword.

Above only lists the monomer services in the future planning for micro service is part of the need to pay attention to simple content, everyone when doing the monomer architecture into micro service will step on a variety of pit, the pit has become our development experience, with these pits can form pay attention to the point, in our next time will have guiding significance to the development. Maybe we programmers thrive on stomping on and filling in potholes.


Personal public account: JaJian

Welcome long press the picture below to pay attention to the public number: JaJian!

We regularly provide you with the explanation and analysis of distributed, micro-services and other first-line Internet companies.