Five petshop business logic layer design
The business logic layer is undoubtedly part of the system architecture that reflects the core value. Its focus is mainly on the formulation of business rules, the implementation of business processes, and other system designs related to business needs, that is, it is the domain that the system is dealing) logic is related. In many cases, the business logic layer is also called the domain layer. For example, in the book patterns of enterprise application architecture, Martin Fowler divides the entire architecture into three main layers: presentation layer, domain layer, and data source layer. Eric Evans, a pioneer in the field-driven design, divided the business logic layer into the application layer and the domain layer in detail, the solution of domain logic and domain logic is further separated by hierarchy.
The business logic layer is critical to the architecture. It is in the middle of the data access layer and the presentation layer, and plays a role in data exchange. Because the layer is a weak coupling structure, the dependency between the layer is downward, and the underlying layer is "ignorant" for the upper layer, changing the design of the upper layer has no impact on the underlying layer of its calls. If the hierarchical design follows the interface-oriented design idea, this downward dependency should also be a weak dependency. Therefore, without changing the interface definition, the ideal layered architecture should be a "drawer" architecture that supports extraction and replacement. Because of this, the design of the business logic layer is critical to an architecture that supports scalability, because it plays two different roles. For the data access layer, it is the caller; for the presentation layer, it is the caller. Dependencies and dependencies are all entangled in the business logic layer. How to decouple dependencies is a task left to designers apart from implementing business logic.
5.1 Cooperation with experts in the field
The biggest obstacle to designing the business logic layer lies not in technology, but in the analysis and understanding of the business in the field. It is hard to imagine that an architecture designer who is not familiar with the business rules and processes in this field can design a system architecture that meets the customer's needs. It is almost concluded that the design process at the business logic layer must involve the participation of field experts. In projects I used to develop, the fields involved cover many industries, such as electric power, semiconductors, and automobiles. If there is a lack of experts in these fields, the design of software architecture, especially the design of the business logic layer, cannot be discussed. The only exception to this conclusion is that the architect is also an expert in this field. However, it is difficult for us to find such an outstanding talent that is "easy to get, but hard to find.
The role of a field expert in a team is usually referred to as business consultor (business consultant). It is responsible for providing consulting related to the field business and participating in architecture and database design with architects, write Requirement documents and design cases (or user story ). If you are in the test phase, you should also include writing test cases. Ideally, domain experts should be involved in the entire project development process, not just the demand stage.
Field experts can be specialized consultants who have deep knowledge in this field, or customers who are demand providers. In extreme programming, customers are introduced into the entire development team as field experts. It emphasizes the on-site customer principle. On-site customers need to participate in various stages of project development, such as planned games, development iterations, and coding tests. As a team of field experts, designers, and developers throughout the development process, the problem of incorrect understanding of requirements can be avoided. Even if the development of the project is inconsistent with the actual needs, it can be corrected in the early stage of the project, which avoids unnecessary project delays and strengthens the control of the project process and cost. As Steve McConnell mentioned in his preparations for building activities, the time for error discovery should be as close as possible to the time for introducing the error. The longer the requirement defect lurks in the system, the more expensive it will be. If you can fully cooperate with field experts in project development, you can avoid such a vicious chain reaction as much as possible.
Traditional software development models also focus on cooperation with field experts, but such cooperation is mainly concentrated in the demand analysis stage. For example, the waterfall model emphasizes early planning and demand research. However, this early planning method requires a high level of skill for architects and demand investigators. It emphasizes the accuracy of the requirement documents. Once the analysis is biased or the demand changes, after the project development enters the design stage, it is difficult for developers to make timely corrections because of the lack of communication and cooperation mechanisms with experts in the field. Once these problems spread like cancer in the system and are gradually exposed to developers, they have become an insurmountable Mountain. We need to spend more manpower and material resources to correct these errors, resulting in an increase in development costs by an order of magnitude, or even project delays. Of course, there is also a good choice, that is, to give up the entire project. There are countless examples like this. In fact, most of the reasons for project development are due to problems in business logic analysis.
Compared with the waterfall model, the iterative model greatly improves because it allows changes and optimization of system requirements. The entire iteration process is actually a process of cooperation with experts in the field, by presenting the system functions generated by iterations to the customer, the customer can get feedback in a timely manner and solve the problems encountered in iterative demonstrations one by one to ensure that the system evolves to meet the customer's needs. Therefore, the iterative model can often solve the problem of insufficient early planning. It allows re-design, re-code, and re-test when detecting defects and changing requirements.
Regardless of the development model used, cooperation with experts in the field will be the key to the success or failure of the project. This is based on the general truth of software development, that is, there is no constant demand in the world. A classic saying goes: "There is no constant demand. The software in the world has been changed more than three times. The owner of the only software that has been changed twice is dead, it's the way to modify the requirement." The cruelty and hardships of software development have been exhausted!
So how should we strengthen cooperation with experts in the field? Based on their experience in the IBM sanfrancisco project, James Carey and Brent Carlson proposed the innocent questions model, meaning "Improving the quality of communication between experts in the field and technical experts ". In a project team, if we do not have one who can serve as both the chief architect and the candidates for field experts, it is particularly important to strengthen cooperation between field experts and technical experts. After all, as an expert in a field, you may not be familiar with the software design methodology or have the ability to develop object-oriented and architectural design. Similarly, most technical experts are likely to stay focused on the business areas involved in the project. If the field experts and technical experts cannot communicate effectively, the future of the entire project will be in danger.
The solutions proposed by innocent questions mode include:
(1) Select a developer who can be in harmony with others to form a development team;
(2) Clearly define roles and permissions;
(3) Clearly define the required interaction points;
(4) maintain a close team;
(5) hire outstanding people.
In fact, this has increased from a technical perspective to a management level for the team. Just like playing basketball, even if your team has set up five of the world's top and most talented players, it is still very difficult to win the game if you want to fight independently. Team spirit and clear rights and responsibilities are the guarantee for victory, as are software development.
The foundation for cooperation with field experts is to ensure that at least one field expert is always retained in the development team. He can be a system customer, a consultant from a third-party company, and ideally an expert hired by his company. If such a person is lacking in the project, I suggest you hire him, if you don't want to see the project suffer a "Siberian cold wave.
Determine the role, tasks, and responsibilities of a domain expert. Each person in the team must specify the roles and responsibilities of the field experts in the entire team. A qualified field expert must have a deep understanding of the business field. He should be a person who can look down on the needs of the entire system and take the overall picture. In the project development process, he is responsible for formulating business rules and processes, communicating with the customer, investigating and discussing requirements, and participating in the design of the system architecture together with the designer. Document editing is a task that must be attended by a domain expert, whether it is a requirement document, design document, or use case writing, a domain expert or comments, or as the author of the writing, at least he should be an important member of the Review Committee.
Standardize the terms and technical terms in the business field. Domain experts and technical experts must communicate with each other in a semantic environment without ambiguity. If there are differences in understanding, we must resolve them in a timely manner and establish terminology standards through discussion. It is hard to imagine that people with different languages can cooperate happily. The solution is to join a translator. It builds a semantic bridge between domain experts and technical experts so that they can understand and recognize each other. Another way is to conduct training activities within the team. Especially for developers, they are more or less familiar with some business fields, which is of great help to project development. During the project development in the semiconductor field that I participated in, the team specially invited experts from the semiconductor industry to give a comprehensive introduction and training on the business logic of the production process. Although we spent the training time, developers who have mastered the business rules and procedures can improve the project development progress and reduce development costs.
Strengthen communication with customers. Customers can also serve as field experts in the team. The on-site customer principle of extreme programming is the best example. However, the reality is not so perfect. When the customer cannot be asked to become a fixed member of the development team, he should hire or arrange a specialized field expert to strengthen communication with the customer, it is particularly important. The project can receive timely feedback from customers through field experts. The field experts can help you understand the needs of changes, minimizing the possibility of demand errors.
5.2 business logic layer pattern application
In his book "enterprise application architecture model", Martin Fowler summarized the architecture model of the domain layer (namely the business logic layer). He divided the business logic design into three main models: transaction script, domain model, and table module.
The transaction Script Mode regards the business logic as a process, and is a typical process-oriented development mode. You can use the transaction Script Mode to directly access the database without the data access layer. To effectively manage SQL statements, you can place database access-related behaviors in a dedicated gateway class. The application of the transaction Script Mode does not require much object-oriented knowledge. The simple and direct feature is the full value of this mode. Therefore, many projects with relatively simple business logic apply the transaction Script Mode.
The domain model mode is a typical embodiment of object-oriented design ideas. It fully considers the complexity and variety of business logic, introduces design patterns such as the strategy model, and implements scalability of the model by establishing domain objects and abstract interfaces, it also utilizes the inherent characteristics of Object-oriented Thinking, such as inheritance, encapsulation, and polymorphism, to process complex and variable business logic. The only application that restricts this mode is the ing between objects and relational databases. We can introduce the ORM tool or use the data mapper mode to map the relationship to the object.
Similar to the domain model pattern, the table module pattern also has the idea of object-oriented design. The only difference is that the object it obtains is not a pure domain object, but a DataSet object. If you create a simple ing relationship between a relational data table and an object, the domain model mode creates a domain object for each record in the data table, the table module mode regards the entire data table as a complete object. Although the use of the DataSet object will lose the basic features of object-oriented, it has a unique advantage in providing data source support for the presentation layer. Especially on the. NET platform, ADO. NET and Web controls provide a fertile ground for the growth of the table module model.
5.3 petshop business logic layer design
Petshop introduces the domain model mode in the business logic layer design, which is inseparable from the data access layer's support for data objects. Because petshop does not go deep into the business logic of the pet online store, and does not omit the business logic of many complicated details, it is not obvious in the application of the domain model. The most typical method is to process objects in the order field, and encapsulate the insert order behavior by introducing the Strategy Mode. I have provided a detailed description in Chapter 27th, so I will not go into details here.
This should have been the core business logic layer in the system architecture design. Due to the simplified business process, the design of petshop at this layer is somewhat poor. Although related domain objects are defined for B2C businesses in the business logic layer, these domain objects only complete simple encapsulation of Data Objects in the data access layer, its purpose is only to separate layers to support expansion of various databases and exclude SQL statements from the business logic layer, avoiding the spread of SQL statements.
In addition to order management, which best reflects the petshop business logic, it also includes the management of shopping cart and wish list. In The bll module of petshop, the cart class is defined to take charge of the relevant business logic. The definition is as follows:
[Serializable]
Public class cart
{
Private dictionary Cartitems = new dictionary ();
Public decimal total
{
Get
{
Decimal Total = 0;
Foreach (cartiteminfo item in cartitems. values)
Total + = item. Price * item. quantity;
Return total;
}
}
Public void setquantity (string Itemid, int qty)
{
Cartitems [Itemid]. Quantity = qty;
}
Public int count
{
Get {return cartitems. Count ;}
}
Public void add (string Itemid)
{
Cartiteminfo cartitem;
If (! Cartitems. trygetvalue (Itemid, out cartitem ))
{
Item = new item ();
Iteminfo DATA = item. getitem (Itemid );
If (Data! = NULL)
{
Cartiteminfo newitem = new cartiteminfo (Itemid, Data. productname, 1, (decimal) data. Price, Data. Name, Data. categoryid, Data. productid );
Cartitems. Add (Itemid, newitem );
}
}
Else
Cartitem. Quantity ++;
}
// Other methods are omitted;
}
The cart class uses a dictionary object to store the content in the shopping cart. It also defines methods such as add, remove, and clear to manage the content in the shopping cart.
As mentioned above, domain objects in the business logic layer of petshop are only simple encapsulation of Data Objects. However, this separation layer method still plays an important role in architecture design. Taking the add () method of the cart class as an example, the petshop. BLL. Item domain object is introduced in the method, and the getitem () method of the item object is called. If the item object is not encapsulated in the business logic layer, but the item data object in the data access layer is called directly, to ensure the weak dependency between layers, you need to call the factory method of the factory object to create petshop. idal. iItem interface type object. Once the item object in the data access layer is called multiple times, duplicate code may occur, which does not leave the program modification and expansion, but also leads to a bloated program structure.
In addition, the encapsulation of Data Objects in the data access layer by domain objects is also conducive to the calling of the business logic layer by the presentation layer. In a three-tier architecture, the presentation layer should be "ignorant" of the data access layer, which not only reduces the dependency between the layer and the layer, but also effectively avoids the consequences of "circular dependency.
It is worth noting that the total attribute of the cart class. The value is obtained by traversing the shopping cart set, and then accumulating the product of the price and the number of items. The business logic is obviously simplified, but the demand expansion is not fully considered. In fact, this algorithm for getting the total price of a shopping cart is only one of the strategies in most cases. We should also consider discounts. For example, when the total price exceeds 100 yuan, you can give the customer a certain discount, which is related to the Promotion Plan of the website. In addition to the Discount Promotion Plan, the website can also consider the gift promotion strategy. Therefore, we need to introduce the Strategy Mode and define the interface ionsalestrategy:
Public interface ionsalestrategy
{
Decimal calculatetotalprice (Dictionary Cartitems );
}
In this way, we can define a constructor with parameters for the cart class:
Private ionsalestrategy m_onsale;
Public cart (ionsalestrategy onsale)
{
M_onsale = onsale;
}
The total attribute can be changed:
Public decimal total
{
Get {return m_onsale.calculatetotalprice (cartitems );}
}
In this way, the cart class can effectively support the promotion plans launched by the website and comply with the open-closed principle. Similarly, this design method is also the embodiment of the domain model. The modified design is shown in Figure 5-1:
Figure 5-1 introduce the Strategy Mode
As a B2C e-commerce architecture, most designers and developers are familiar with the business fields involved. In this example, cooperation with experts in the field is not so important. However, if we want to develop a successful e-commerce website, cooperation with experts in the field is still indispensable. In terms of order management, if complicated commercial applications are considered, it is necessary to manage order tracking, cooperation with online banks, Account Security, inventory management, and logistics management, and Customer Relationship Management (CRM ). The entire business process covers many fields, such as e-commerce, banking, logistics, and customer relationship. without the participation of field experts, the design of the business logic layer may fail ".
5.4 communication with the data access layer
The business logic layer needs to communicate with the data access layer to access the database through the data access layer. Therefore, there is a dependency between the business logic layer and the data access layer. When the interface assembly and data factory are introduced in the data access layer, the relationship between the two is weak dependency. We can see from the reference assembly of the business logic layer that The bll module does not reference the sqlserverdal and oracledal assembly. In the business logic layer, for calling Data Objects in the data access layer, the principle of polymorphism is used to define abstract interface type objects, then, use the factory method of the factory object to create a specific data object. As shown in petshop. BLL. petshop objects:
Namespace petshop. BLL
{
Public class product
{
// Create an iproduct interface type instance based on the factory object;
Private Static readonly iproduct Dal = petshop. dalfactory. dataaccess. createproduct ();
// Call the interface method of the iproduct object getproductbycategory ();
Public ilist Getproductsbycategory (string category)
{
// Create a list object if it is null;
If (string. isnullorempty (Category ))
Return new list
();
// Access the database through data objects at the data access layer;
Return Dal. getproductsbycategory (category );
}
// Other methods are omitted;
}
}
In the product class of the domain object, the factory class dalfactory. dataaccess of the data access layer is used to create an instance of the petshop. idal. iproduct type, so that the dependency on the specific Assembly sqlserverdal or oracledal can be removed. As long as the petshop. idal interface method remains unchanged, the implementation of the business logic layer will not be affected even if the implementation of the idal interface module is modified. This loose weak coupling can maximize the scalability of the architecture.
In fact, the product of the domain object encapsulates the product of the data object. The interface methods exposed by the domain object are the same. It is through encapsulation that the presentation layer can be completely separated from the database and data access layer, the caller of the presentation layer only needs to focus on the implementation logic of the business logic layer, as well as the interfaces and calling methods exposed by domain objects. In fact, as long as the design is reasonable and interface methods at all levels are standardized, the design of a three-tier architecture can be fully developed by different developers at the same time, which can effectively use development resources, shorten the project development cycle.
5.5 interface-oriented design
It may be because the business logic is relatively simple. In the design of the business logic layer, it does not follow the idea of interface-oriented design in the data access layer. In addition to the abstraction of the insert order policy, the entire business logic layer is implemented only by The bll module and there is no abstract interface defined for domain objects. Therefore, the presentation layer of petshop has a strong dependency with the business logic layer. If the requirements in the business logic layer change, the implementation of the presentation layer will inevitably be affected. The only thing we can be pleased with is that, because we use a layered architecture to completely separate the user interface from the business logic, once the user interface is changed, for example, if you change the B/S architecture to the C/S architecture, the implementation modules of the business logic layer can be completely reused.
However, the most ideal method is interface-oriented design. According to chapter 1 of ASP. net cache analysis, we can divide the proxy class and Utility Class under the presentation layer app_code into the business logic layer, and modify these static classes as instance classes, abstract The methods related to the business fields in these classes as interfaces, and then create an abstract factory like the data access layer. Through the "dependency injection" method, the dependency on object classes in specific fields is removed, so that the presentation layer only depends on the Interface assembly and factory module of the business logic layer.
So, is there any suspicion of "over-design" such a design? We need to decide based on the requirements of the business logic. In addition, if we need to introduce the cache mechanism to create proxy classes for domain objects, it is especially necessary to create interfaces for domain objects. We can establish a special interface module ibll to define the interface of the domain object. Taking the product domain object as an example, we can establish the iproduct interface:
Public interface iproduct
{
Ilist
Getproductbycategory (string category );
Ilist
Getproductbycategory (string [] keywords );
Productinfo getproduct (string productid );
}
The dependencies on ibll assembly can be introduced in the BLL module. The domain object product is defined as follows:
Public class product: iproduct
{
Public ilist
Getproductbycategory (string category) {// implementation omitted ;}
Public ilist
Getproductbycategory (string [] keywords) {// implementation omitted ;}
Public productinfo getproduct (string productid) {// implementation omitted ;}
}
Then we can create a special assembly bllproxy for the proxy object, which not only introduces dependencies on the ibll assembly, but also depends on the BLL assembly. The proxy object productdataproxy is defined as follows:
Using petshop. ibll;
Using petshop. BLL;
Namespace petshop. bllproxy
{
Public class productdataproxy: iproduct
{
Public ilist
Getproductbycategory (string category)
{
Product = new product ();
// Other implementations;
}
Public ilist
Getproductbycategory (string [] keywords) {// implementation omitted ;}
Public productinfo getproduct (string productid) {// implementation omitted ;}
}
}
Such a design is a typical proxy mode. Its class structure is 5-2:
Figure 5-2 proxy Mode
With reference to the data access layer design method, we can establish abstract factories for domain objects and proxy objects, and. configure related configuration sections in config, and then use reflection technology to create a specific object instance. In this way, the presentation layer can only depend on the petshop. ibll assembly and the factory module, so that the dependency between the presentation layer and the objects in specific fields can be removed. The relationship between the presentation layer and the modified business logic layer is as follows:
Figure 5-3 Relationship Between the modified business logic layer and the presentation layer
Figure 5-4 shows the hierarchical relationship diagram of the original design of petshop 4.0:
Figure 5-4 Relationship Between the presentation layer and the business logic layer in petshop 4.0
Compared with Figure 5-3 and figure 5-4, although the latter is relatively simple, regardless of the number of modules or the relationship between modules, however, the Web component is strongly coupled with the business logic layer. Such a design is not conducive to business expansion and demand changes. By introducing the interface module ibll and the factory module bllfactory, dependencies with specific modules Bll are removed. This design is more in line with the object-oriented design philosophy for systems with relatively complex business logic, and is conducive to the establishment of a three-tier architecture that can be extracted and replaced.