Analysis Patterns - Reusable Object Model

Recently read the book “Analysis Patterns - Reusable Object Model”, this book is considered an enlightening book on DDD, read the completion or benefit a lot, on the one hand, many points and the usual work of mutual evidence, very inspired, on the other hand, learned some business modeling patterns, this article mainly summarizes the inspiration received This article mainly summarizes the inspiration received and modeling principles, specific modeling approach to give an example to experience it.

Here are a few of my most rewarding points in brief:

  • An important principle of object development is that the structure of the software reflects the structure of the problem.
  • The coupling caused by the problem not sorted out clearly is not solved by design patterns, such as logistics and orders, they use the same data table, they need to sense each other, then they must be coupled together in some way, belonging to the essential complexity, this coupling is not decoupled by a good design pattern, even if they are two systems, they have to be together alteration.
  • The division of business areas should also achieve high cohesion, low coupling, the principle of least knowledge, if each business area needs to know a lot of other business areas of knowledge, then in fact, or coupling.
  • If there have to be connections between different domains, try to minimize two-way connections, each of which introduces higher complexity into the system.
  • In the beginning of the system to minimize the complexity of the system at the same time, keep open to changes, that is, the principle of open and closed, unless very necessary, do not come up to introduce a lot of third-party tools, to consider the introduction cost of these tools, maintenance costs, upgrade costs, and even opportunity costs, and do not come up to engage in any microservices, microservices are best from a mature system after verification of stable business areas Microservices are best incubated from a proven and stable business area in a mature system, otherwise, microservices on pure technical architecture will only increase the overall complexity and risk of the system.

Introduction

**We can simply divide the architecture design into horizontal and vertical divisions. The horizontal division, which addresses the business architecture, is to reduce the essential complexity of business logic and reduce the coupling between business domains, while the vertical architecture addresses non-functional requirements, such as improving stability, throughput rates, etc. through technologies such as caching layers, message queues, etc. **

Our focus in this paper is to address some of the principles of horizontal architectural design.

The purpose of analysis is to understand the problem, which, in my opinion, can be more than just a process of using use cases to enumerate requirements. Use cases are valuable, if not essential, in the system development process, but capturing such use cases does not mean the end of the analysis. Analysis also involves looking beyond the surface requirements to propose a mental model that reflects the underlying mechanisms of the problem.

Consider writing software that simulates a billiard game, which can be evaluated by describing the use case of a surface feature: “The player hits the white ball, causing it to move at a certain speed, and then the white ball hits the red ball at a certain angle, causing the red ball to move a certain distance in a certain direction.” One could shoot such an event hundreds of times and measure the speed, angle and distance the ball moved. However, I am afraid that this alone is not enough to write a good simulation program. To write a good program, one needs to look beyond the surface phenomenon to understand the underlying laws of motion, including mass, velocity, momentum, etc.

Problems like the game of billiards are not rare because the laws of these sports are widely known. Then in many companies, the basic mechanisms at this level are not well understood and need to be diligently discovered.

There is no right or wrong model, the key is which model is more suitable.

The choice of model may affect the flexibility and reusability of the developed software. For software like a billiards tournament, you might advocate using the Einstein model because the developed software can be flexible enough to handle atomic collision problems. But this is a more dangerous way to handle it, because introducing too much flexibility may lead to an overly complex system, which is a bad engineering practice.

One of the main reasons for using analysis and design techniques is to involve domain experts, which is essential for conceptual modeling. Effective models can only be built by people who really understand the domain, people who work full time in the field. it skills neither help nor hinder modeling skills.

Analytical techniques should be independent of each other and software techniques, and ideally, conceptual modeling should be completely independent of software techniques, as in the case of the laws of motion described above. This independence prevents the technology from hindering one’s understanding of the problem, and the resulting model is equally valid for all software technologies.

Closely related to the conceptual model is the software interface rather than the software implementation.

Some modeling principles

Here is a list of some modeling principles in the book, in fact, these principles and the principles of design patterns are similar, they just focus on different points.

  1. The modeling should minimize the number of types affected by the part of the model that changes most frequently. (This point is actually related to the design pattern’s separation of parts that are prone to change from those that are not.)
  2. When defining characteristics for types with supertypes, consider whether it makes sense to place these characteristics on the supertype.
  3. The model should be explicitly divided into an operational layer and a knowledge layer. For example, the configuration class files or some custom semantics that we can parse are the knowledge layer, which defines the relationships between classes and certain principles of program operation, while the specifics of how to instantiate classes belong to the operational layer.
  4. When multiple attributes interact through behaviors that can be used in several types, these attributes should be combined into a new basic type. For example, if our system involves a large number of different units of data, we can combine units and values from these data into a quantity type.
  5. The operational layer contains those concepts that change on a daily basis and whose configuration is bounded by the knowledge layer, which will change much less frequently. The frequency of change here refers to runtime changes.
  6. If a type has very many similar associations, then abstract these associated objects into a new type and then create a knowledge layer to distinguish them.
  7. To record the change history of a value, an account should be created for that value.
  8. When using the account, the following conservation principle should be followed: the recorded items cannot be created or destroyed, and can only be transferred from one place to another, which makes it easier to find and avoid vulnerabilities.
  9. To understand how a calculation is performed, you can represent the result of the calculation as an object that is used to remember the calculation that created it and the input values that were used.
  10. When there are multiple equivalent feature sets to choose from, pick the one that the domain expert thinks is most appropriate, and if the domain expert thinks both are very valuable, then extract both and mark one of them as a derivation.
  11. Marking a feature as derived is only a constraint on the interface and does not affect the underlying data structure.
  12. If a collection of objects can be created by different conditions, then a combination should be used.
  13. When treating a process as a feature of a type, an abstract interface should be provided for the process so that its implementation can be easily changed through subclassing. For example, purely hard-coded implementations are one subclass, and various parameter-driven methods are other subclasses.
  14. When multiple attributes interact in a behavior that may be used in more than one type, the attributes should be combined into a new basic type.
  15. If the supertype applies to a narrower domain and the subtype applies to a wider domain, then generalization should not be used.
  16. If the difference between two similar types is usually negligible, then use the abstract supertype. If the difference between the two is important, then do not use the abstract supertype.
  17. If using an abstract supertype does not cause more work for the client, then this abstract type should be provided.
  18. When some information may be both obtained directly from a source and calculated from other available data, an abstract interface should be provided with the two ways of obtaining and calculating information from the source as their respective subclasses.
  19. When faced with several alternative methods, first choose the simplest method and then change to a more complex method as needed.
  20. Follow the intuition of domain experts when it is difficult to choose among immediate modeling solutions.
  21. Subtyping should only be used if all the characteristics of the supertype apply to the subtype and it is conceptually reasonable to say that every instance of the subtype is an instance of the supertype.
  22. When the customer perspective sees that a single transaction can be divided into multiple transactions by the trader, the product and the contract should be separated. The key to the product-contract distinction is that the product represents the client’s intent, while the contract refers to the content of the actual transaction between the counterparty and the principal.
  23. Do not repeat basic associations that have the same meaning. By following this principle, it is possible to obtain well-defined types of responsibilities.
  24. There should be consistency in the assignment of responsibilities. Beware of the types who sometimes take responsibility for something and sometimes delegate that responsibility. (This behavior may be correct, but it should always be viewed with suspicion)
  25. The choice between one-way and two-way associations requires a trade-off between low workload for type development staff (reduced coupling between types) on the one hand, and ease of use for type users on the other.
  26. If a package only needs to see part of another package, consider splitting the latter package into two mutually visible packages.
  27. The essence of subtyping is that it can be extended without the supertype knowing anything about it. It is often necessary to design some subtypes to gain experience and then abstract them.

Two examples of analysis patterns

Each box in the diagram represents a type.

Responsibility mode

  • The responsibility type is defined in the knowledge layer, and the responsibility type defines what kind of delegates can be selected by the responsible party which mapping relationship
  • Then the operational layer is to instantiate a responsibility, and to follow the specification in the responsibility type of the knowledge layer when re-selecting the participants in a specific responsibility
  • Each responsibility may have a time period that corresponds to an activity.

Observer Pattern

  • Each observation has its own participant
  • Observations can be subtyped as hypothetical, speculative and valid observations
  • Observations can also be subtyped as measurements and categorical observations, where the result of a measurement is a quantity (value + unit) and the result of a categorical observation is the presence or absence of it. As an example, blood pressure is a measurement, while high blood pressure is a categorical observation. Blood pressure, a measurement, can be inferred from blood pressure high, a categorical observation, and once the blood pressure measurement is wrong, this chain of inference should be directly negated by the chain.
  • At the knowledge level, observation has its own protocols, that is, how it is carried out
  • The type of phenomenon in the knowledge layer, phenomenon and observation concept, specifies what the observation in the operational layer can be, e.g. blood pressure is a type of phenomenon, increase is a phenomenon, and increase in blood pressure is an observation concept, while observation concepts are inferred from each other.