The object-oriented design concept of software systems has a long history. The Smalltalk in 1970s can be said to be a classic of object-oriented language. Today, we still regard this language as the basis of object-oriented language. With the development of programming languages and technologies, various language features emerge one after another. Object-oriented is a basic feature of most languages, such as static languages such as C ++, Java, and C, dynamic languages such as Ruby and Python are object-oriented languages.
However, object-oriented language is not a silver bullet. If developers think that programs written in object-oriented language are object-oriented, it is a big mistake. In actual development, A large number of examples of business logic accumulation in a giant class are not uncommon, and the reusability and scalability of Code cannot be guaranteed. In order to solve this problem, the domain-driven design puts forward a clear hierarchical architecture and the concept of domain objects, bringing the object-oriented analysis and design into a new stage, it has played a huge role in promoting enterprise-level software development.
This article mainly introduces the basic concepts, elements and features of the domain-driven design, compares the features of the transaction script and the domain model, and finally introduces our domain-driven design practices in the software development process.
What is domain-driven design (DDD)
In 2004, Eric Evans, a famous modeling expert, published his most influential book domain-driven design-tackling complexity in the heart of software: domain-driven design-the way to cope with the core complexity of software), the book introduces the concept of "Domain-driven design (DDD.
In fact, the field-driven design is an extension of OOAD. Based on the object-oriented analysis and design technology, DDD conducts hierarchical planning of the technical architecture, meanwhile, policies and types are divided for each class.
Domain Model is the core of domain-driven development. With the design philosophy of DDD, the business logic is no longer concentrated on several large classes, but composed of a large number of relatively small domain objects (classes). These classes have their own States and behaviors, each class is a relatively complete and independent body that maps to Business Objects in the real world. The domain model is composed of many fine-grained classes. The domain-driven design ensures the maintainability, scalability, and reusability of the system and has inherent advantages in processing complex business logic.
Features of domain-driven design
The domain-driven core application scenario is to solve the design problem of complex businesses. Its characteristics are closely related to this core topic:
- Layered Architecture and Responsibility Division: the domain-driven design follows the principle of separation of concerns and proposes a mature and clear layered architecture. At the same time, the domain objects are clearly defined strategies and responsibilities, so that the domain objects can form a good ing relationship with the real-world businesses and build a bridge for communication between domain experts and developers.
- Reuse: in the field-driven design, the domain object is the core, and each domain object is a relatively complete and cohesive business object description, so it can be directly reused. At the same time, the design process is based on the domain object rather than the database schema, so the entire design can be reused.
- Application Scenario: Suitable for software systems that have complex business logic, and have high requirements on Software maintainability and scalability. It is not applicable to simple addition, deletion, modification, and query services.
If you do not use DDD?
In the face of complex business scenarios and needs, if you do not establish or implement a domain model, the application architecture will have a "Fat service layer" and "anemia domain model". In this architecture, the service layer begins to accumulate more and more business logic, and domain objects become data carriers with only getter and setter methods. This approach also leads to the spread of domain-specific business logic and rules across multiple service classes, and repeated logic may occur in some cases. We have seen over 5000 service lines, hundreds of methods, and code is basically unreadable.
In most cases, the anemia domain model has no cost-effectiveness. They do not give the company a competitive advantage that surpasses other companies, because it takes too long to implement business needs changes and develop and deploy them in the production environment.
Layered Architecture and components of domain-driven design
Next we will briefly introduce the layered architecture and components of the field-driven design. This part of content is described in a very detailed manner in Eric Evans's book. If you want to know more, you 'd better read the original book.
The following figure shows the famous layered architecture in the book, as shown below:
The entire architecture is divided into four layers, the core of which is the domain layer. All business logic should be implemented at the domain layer. The specific description is as follows:
User Interface/Presentation Layer |
Displays information to users and explains USER commands. |
Application Layer |
A thin layer is used to coordinate application activities. It does not contain business logic. It does not retain the state of the business object, but it retains the progress state of the application task. |
Domain Layer |
This layer contains information about fields. This is the core of business software. The state of the Business Objects is retained here, and the persistence of the business objects and their States is delegated to the infrastructure layer. |
Infrastructure Layer |
This layer is used as the support stock for other layers. It provides layer-to-layer communication for Business Object persistence, including supporting libraries for the user interface layer. |
In addition to the hierarchical description of the system architecture, the domain-driven design also clearly defines the responsibilities and policies of objects:
- Entity: has a unique ID, can be persisted, has business logic, corresponds to real-world business objects.
- Value objects: it does not have a unique ID and is described by the attributes of the object. It is generally a temporary object in memory and can be used to pass parameters or provide a supplementary description of the object.
- Factories: Mainly used to create entities. Currently, IOC containers are generally used in architecture practice to implement factory functions.
- Repository: used to manage object sets and encapsulate Persistence frameworks.
- Services: provides operational interfaces for superstructure, schedules and encapsulates domain objects, and provides various forms of services.
Of course, the concept of aggregate root is also proposed in DDD. However, in practice, we find that the problem of aggregation root is complicated, it is easier to describe the relationship between objects in a domain by using traditional concepts such as aggregation and combination. Therefore, we will not introduce this concept here.
Transaction script and Domain Model
Chapter 9 domain logic patterns in the patterns of enterprise application architecture written by Martin Fowler in 2004) and domain model (domain model), understanding these two models is very helpful for designing and building enterprise application software, so it is necessary to introduce.
Transaction script:
The core of the transaction script is the process. The business logic is organized through the call of the process. Each process processes a single request from the presentation layer. Most business applications can be considered as a series of transactions. To some extent, using transaction scripts to process businesses is like executing SQL statements to process database information. The transaction script organizes the business logic into a single process and calls the database directly during the process. The business logic is processed at the service layer.
The transaction script mode can be shown in UML charts as follows:
The action layer processes the action requests at the UI Layer, assembles the data in the request, and passes the data to businessService. After the BS layer performs simple logic processing, it calls the Data Access Object for data persistence, specifically, Vo acts as a data transmission object. Generally, it is an anemia pojo. It only has the getter and setter methods and has no status or behavior.
The transaction Script Mode is easy to understand and process-oriented. For a few logical business applications, the transaction Script Mode is simple and natural, with good performance and easy to understand, and the processing of one transaction does not affect other transactions. However, the disadvantages are also obvious. It is difficult to maintain a good design for complicated business logic processing, and the redundant code between transactions is increasing, which is reused by means of copy and paste. Maintainability and scalability are deteriorated.
Domain Model:
The domain model has obvious characteristics and is an object-oriented design. The domain model has its own attribute behavior status and is mapped to the real-world business objects. Each type has a clear division of duties, and the domain object elements are combined with each other to solve actual business applications and rules. Reusable, maintainable, and scalable. A proper design model can be used for detailed design. The disadvantage is that it is relatively complex and requires the designers to have good abstract capabilities.
The domain model corresponds to the domain layer defined in the domain-driven design, which will not be discussed in detail here.
In actual design, we need to select the appropriate design mode based on specific needs. The core business system with complex business logic is suitable for the use of domain models. The transaction script mode can be considered for a simple information management system.
Domain-driven design practices
The following describes the practices and extensions of DDD in building an enterprise-level application development platform.
I have been engaged in enterprise-level application development platform work in recent years. Gap platform is a software product used to solve questions such as reuse, rapid development, and process standardization in enterprise-level software development. To design such a platform, we should be able to support the construction of systems with complex business logic from the underlying framework. Therefore, we have adopted the idea of field-driven design in the Design of Large architectures, the layer-4 architecture of DDD is refined and implemented based on the actual technology and functions to be implemented:
The entire platform adopts javaee Technology and Its Related open-source framework. The core business logic of the system is processed by the domain layer. The business service is responsible for processing a relatively cohesive business logic unit, and providing local or remote services to external users.
The following is a brief description of each layer:
- View: Display layer. Because the gap platform is mainly oriented to the B/S architecture, the display layer consists of web resource files, including JSP, JS, and a large number of interface controls, it also uses Ajax, flex, and other RIA technologies to present rich interface information to users and execute USER commands.
- Control: the control layer is responsible for displaying request forwarding, scheduling, and basic verification at the layer, and automatically intercepts the runtime exception information returned by the background. If the control layer needs to interact with a third-party system, remote requests can be made through action.
- Domain: the domain layer is the most abundant layer of the system. It is mainly responsible for processing the business logic of the entire system. This layer includes business services and domain objects, and is responsible for system transaction management. The business service can call and share remote services locally.
- Persistence: persistence layer, mainly responsible for data persistence. It supports o/R Mapping and JDBC. Data sources can be accessed in multiple ways.
In addition, we introduced spring's IOC container. The elements of the control layer, domain layer, and persistence layer of the system are all managed in a uniform way by IOC container, achieving full interface separation and decoupling. At the same time, Log service can be referenced at the control, domain, and persistence layers.
Our definition of the driving factors in the field is slightly different from the original naming and meaning.
The original service is defined as the business service. The service-oriented architecture is the core design concept of the GAP platform, A business service can be composed of one or more domain models and data access objects (DAO) to implement a complete business logic unit. The business service is mainly responsible for processing and maintaining the relationships between objects in various fields, and providing local and remote services for upper-layer access. The service types include web service and RMI.
A domain object consists of an object (entity) and a value object (VO). An object class has its own attributes, behaviors, and States, and can aggregate VO. Entity classes can have aggregation and association relationships, the Data Access Object (DAO) can be used for persistence.
Persistence is implemented by the Data Access Object (DAO), which is mainly responsible for Object Persistence without processing the business logic. Multiple persistence methods (O/R Mapping and JDBC) are provided ).
So how can we implement a domain-driven design? We have summarized the following four steps:
- Business Service: Determine the business unit based on the business requirements and functional modules. Each business service is an internal business unit covering the relevant fields.
- Define the domain object (entity, VO): defines the domain object based on the business logic of the business unit, and describes the domain object through the UML method and design mode.
- Define the attributes and associations of domain objects: determine the various attributes of domain objects and their associations.
- Add behavior to domain objects: Add behavior to domain objects based on business needs (system cases and interface prototypes) and define the methods to be referenced by business services.
Case study: Online Bookstore
In order to better understand the field-driven design, we have implemented a simple online bookstore system based on the above design method.
The online bookstore system is an example of an application system built using the DDD design idea. Through the online bookstore system, you can quickly understand the field-driven design. This system provides common functions for online bookstores: browsing books, selecting books, submitting orders, viewing orders, automatic discounts, processing orders, and canceling orders. Unlogged users can browse and select books. logged-on users can submit and view their own orders. administrators can process orders.
After business abstraction, even such a simple business scenario involves many domain objects, such as orders, accounts, books, shopping carts, shopping items, discounts, etc. Through analysis and design, we can get this design diagram (for ease of viewing, the class in the diagram hides the attribute information ):
Bookstoreaction is responsible for processing the requests at the presentation layer and forwarding the requests to the business service ibookstorebs. The business service is responsible for scheduling the domain objects displayed in the scenario to process all the businesses in this scenario.
The correspondence between domain objects and real services is as follows:
- Account -- account
- Order -- order
- Book-books
- Cart -- shopping cart
- Item -- order item
- Discount -- discount
Unlike the transaction Script Programming mode, the domain-driven design does not place the business logic in BS (businessService), but is processed by domain objects with attributes, behaviors, and States. For example, for the Order class, if it is a pojo with anemia, it only has the attributes corresponding to the data table fields and the getter and setter Methods internally. In the field-driven design, it is a relatively independent domain object that can process its associated services. In this system, the order is described as follows:
The implementation class of an order is gap. template. Bookstore. model. Order. In addition to basic attributes such as contact information and mailing address, the class also involves the following fields:
- Init (...), called during settlement, initializes the order based on the current user and the items in the shopping cart for the user to modify.
- Submit (...), the method called when submitting the order, save the order.
- Cancel (...), cancel the order, set the status of the order and related items to "canceled", and then delegate Dao for persistence.
- Dispose (...), process the order, first update the status of the order item, and then delegate Dao to persist the order data.
- Resubmit, setitemsstatus ......
Through the above description, we can see that the Order class basically covers all the behaviors and states of the Order business in the real world, which are relatively cohesive, this feature greatly increases the reusability of the Order class. Even if a new module is developed in the future that involves the order business, the Order class can be reused directly. At the same time, if I want to know the business of the order, I can simply read the Order code.
We can also clearly see the relationships between objects in various fields. Order and cart aggregate item, corresponding to 1... n, item aggregates book, corresponding to 1... 1. Order is associated with discounts, accounts, and calls. The scenario of the online bookstore is described as follows.
In addition to infrastructure (transaction management and service sharing), BS is also responsible for scheduling and maintaining the relationship between objects in the field. Because there will always be some business logic that does not belong to or belong to this field, who will handle this part of the business? It is handled by BS. For example, if the administrator processes an order, he must first obtain an account based on the order information, determine the discount rate based on the account information, and verify the balance, the dispose method of the Order object is called to process the order. This scenario involves objects such as order, account, and discount. Such business logic should be implemented by BS.
Ibookstoredao is a data access object. It can be called by BS for persistence objects, or can be referenced by domain objects to persist itself.
Through the above description, we can see that the entire design and implementation are elegant and clear. Business logic is not accumulated in BS, but scattered in BS and objects in various fields. Services and objects are closely related to real-world businesses, both domain experts, developers, and maintenance personnel can obtain the content they need in this way.
Summary
We adopt a domain-driven design relatively early. As far as my personal test and practice are concerned, DDD plays a significant role in building an enterprise-level application development platform and a large core business system, the product has been significantly improved in terms of product stability, scalability, maintainability, and lifecycle.
However, for such reasons (complexity, duration, limitations on developers' capabilities, etc.), many may unconsciously resist using DDD. Sometimes, a software project is rewritten twice, for the second time, we still do not do a good design. In fact, we have adopted the design method of DDD, and our design stage has become very lightweight and agile. As long as developers can draw out and describe the relationship between domain models, and reach an agreement with the demand personnel, then the things made are basically reliable.
In the field of technology, only proactive attempts and improvements are most effective. Many people have asked me how to start learning and practicing XXX, which is actually very simple. Let's start now!
References
Domain-driven design-how to deal with core software complexity, by Evans Eric, Addison-Wesley Press
Enterprise application architecture model, by Martin Fowler, Addison-Wesley Press
Domain-driven design and practices