Basic Design Principles
Writing code that can work normally is one thing, and writing good code that can work normally is another thing. A well-designed system is not a series of commands and patching. There are many things that are directly or indirectly related to the design. Compared with other quality features defined in international standards, you need to pay more attention to code maintainability. The reason for choosing this feature is not because other features (such as scalability and scalability) are less important than maintainability, however, maintaining code maintainability is costly and easy for developers to ignore. maintenance is the most critical issue in the system.
There are two points to resolve maintainability. Structured Design is the first element, which can be ensured by a series of coding technologies. The readability of the Code is another important factor. If the Code comes with a lot of internal documents and appropriate change tracking systems, it is not difficult to implement it. In fact, a perfect system will only appear in a perfect world.
There are still incomplete requirements for poor designs. So naturally, agile development is the best way to improve communication and meet requirements. agile methods can bring continuous communication between teams and customers. However, you should also be careful that agile development methods will unconsciously increase development costs and increase demand. In the agile process, you must ensure that everyone in the process can understand the reason for doing so. The stakeholders of the Project do not understand the roles and do not cooperate, or cannot summarize them between iterations, agile Methods won't succeed.
In the design process, avoid making the software design too hard. The so-called hard refers to the software that has a large conflict with those modifications. Resistance is measured by the ability to recover. If a module is modified, and you have to modify the dependent module, it is difficult to predict the cost of a modification. In many cases, we only modify bugs temporarily. In general, temporary modifications are not much faster than a thorough solution, temporary patching will not cause too many adverse effects to the entire design. However, this is a bad signal. Such a design is usually called high viscosity, high viscosity is not a good thing, because it means that the software is difficult to modify, just like high viscosity liquid is not easy to flow.
Structured Design
From the beginning of the concept of structured design, the hidden core principles of structured design have been today's guiding ideology. The two principles of high cohesion and low coupling are infinite in the object-oriented world. The higher the cohesion, the better the software design. Highly cohesive modules mean maintainability and reusability, because these modules have little external dependency. Low cohesion modules are easy to depend on other modules, making the software hard and highly viscous. Coupling is measured from low to high. The lower the coupling, the better the software design. High Cohesion and low coupling are mutually dependent. If the system meets these two conditions, the system has basically met the requirements of high readability, high maintainability, easy to test and easy to reuse.
Separation of concerns
When we design the system to consider the factors of cohesion and coupling, separation of focus helps us achieve this goal. The core of the separation focus is to split the system into different functions, and it is best not to overlap. The separation focus principle suggests that we only process one focus at a time. This does not mean that all other concerns should be left behind at this time, but that when you decide to use a module to implement this focus, you only need to concentrate on implementing this module. From this perspective, other concerns are irrelevant. Specifically, separation focuses on implementation through modular code and extensive application of information hiding. Modular programming encourages us to use different modules to implement different functions. The module has its own public interface and can communicate with other modules. The module also contains a large amount of internal information for its own use. Information Hiding is a general design option. Fixed public interfaces hide the Implementation Details of software modules to reduce the impact of future changes.
In fact, the first supported programming concept for separation of focus is procedural programming. In procedural programming, separation of focus depends on functions and processes. However, the concept of separation of focus is not limited to programming languages. It goes beyond the pure programming field and applies to many aspects of software architecture. In Service-Oriented Architecture SOA, services are used to represent concerns. The layered architecture is also constructed based on the principle of separation of concerns.
Object-Oriented Design
Object-Oriented Design is a milestone. An important step in object-oriented design is to find a clean and flexible abstraction for the problem field. To complete this step well, you should consider things rather than processes. We should focus on "what" rather than "how ".
Reusability is a very important aspect of the object-oriented concept, and it is also the root cause of the widespread use of object-oriented. The author of design patterns summarizes two reuse methods: white box reuse and black box reuse. The former is based on inheritance, and the latter is based on object combination. In actual design, try to use object combinations instead of type inheritance. In real-world projects, object combinations are safer and easier to maintain and test. Modifying composite objects in a combination does not affect internal objects.
In addition to the combination, another method is also commonly used to compare with the type inheritance, that is, aggregation. The difference between a combination and an aggregation is that there is a static association between the container and the internal class in the combination, and the internal class of the container will be destroyed if it is destroyed. In aggregation, the relationship between the two is weak. Even if the container is destroyed, key classes can still be used.
Advanced principles
In recent years, the principles of cohesion, low coupling, and separation of concerns have been further evolved and enhanced. The following are three advanced principles.
The principle of open and closed. It helps the units (including types, functions, or modules) in the software to adapt to changes more easily. In each change, you need to add new code to enhance the existing type of behavior, instead of modifying the original code. Currently, the best way to achieve this principle is to provide a fixed interface and then enable classes that may change to implement this interface. Then the caller operates based on this interface.
Lee's replacement principle. When a type is derived from an existing type, the derived class can be used in any place where the parent class can be used. This is polymorphism. The principle of openness and closure is closely related to the principle of the replacement of RYS. Any method that violates the principle of the replacement of RYS cannot meet the principle of openness and closure.
Dependency inversion principle. The "invert" in the principle name indicates that the top-down mode should be adopted in the implementation process, and the workflow of this module should be focused on the high-level level, rather than the specific implementation of the low-level module. In this case, low-level modules can be directly inserted into high-level modules.
From principle to Mode
From a high point of view, the industry generally recognizes two software models: Design Model and architecture model. We use the design pattern when designing and coding. In the general design of the planning system, we will use the architecture model. Another mode worth introducing is the refactoring mode. Common refactoring modes include "extraction interface" and "encapsulated field.
Each of their modes describes a problem that occurs in our environment over and over again. The model also provides the core solution for this problem. This solution is reused once and again, without the need to start over each time. A design model is a core solution that has been widely used and is suitable for solving a special problem that may occur during the implementation process.
However, the design model is not omnipotent and cannot be used as a dogma. The design model is not a Superman and cannot save a project in the quagmire. The design pattern may be with you, but it will not bring you additional capabilities. Design Patterns are just useful. The most common error in using design patterns is to view each pattern one by one, and then apply it to a specific issue. On the contrary, the mode should be used in turn to solve the existing problems. The use of design patterns does not in essence make your solutions more valuable. The real value lies in whether your solutions can work normally and meet your needs during delivery.
When you get a complete solution, systematic application of design principles will bring you to a known design pattern either early or late. The reason for such determination is that the model is the solution to the problems that others have encountered and classified. The model does not add value to the solution. The value lies in providing solutions for architects or developers.
Reverse Mode
There are material and antimatter points in physics. Similarly, in software, we use patterns to form a solution and reverse patterns to form a reverse solution. The difference between the two lies in that the pattern can give us a good solution, while the reverse pattern will bring us a bad solution. Anti-pattern is a pattern that describes how to evolve from a problem to a bad solution. The basic principle of anti-pattern is that these patterns seem like a good design at the beginning, adding new features or improving efficiency for your type. In fact, the anti-pattern will gradually lead you astray, resulting in far more trouble than the benefit.
Designers and anti-patterns will attract each other to some extent, but sophisticated designers will recognize the sugar shell and try their best to avoid it. There are many anti-patterns. Here are two examples.
The "architecture as demand" anti-pattern refers to the fact that an influential member of the design team insists on using an immature technology or product in the project, even if there is no evidence to indicate its role or whether it applies to the context.
The anti-pattern of "using release as a test" means that software products are not too concerned with boring unit tests or integration tests during release. Users are the end users of products, so they should check the software quality.
Security as a requirement
Security is a much more complex process than you think. If engineers do not understand basic security principles, common security defects, and basic security design or security testing, they are absolutely impossible to write secure software. Security must be carefully grasped from the very beginning. Security design begins with the architecture, rather than something that can be supplemented later. Security is determined by the design. If you want to handle security issues, you should choose a development method that focuses on security so that you can always remember security when designing the system.
SDL, secure development lifecycle is a development process that Microsoft uses internally to improve software security by reducing security bugs. SDL is actually an iterative process, focusing on the security aspects of the software process. The cornerstone of SDL is divided into three layers: hierarchy, componentization, and role. For example, layering brings benefits to the data server. It puts security checks on the business layer so that the only user data layer can access the database, use code access security in business components to prevent operations that require permissions for untrusted code execution. Componentization means that the components that require security protection are differentiated. It does not mean that the logical architecture is divided into one assembly. For each component, we need to determine the minimum permission set for their normal operation. A role is a logical attribute assigned to a user. The role represents the user's location in the application context. In the role-based security model, risks Caused by disguised user or delegated execution can be effectively reduced.
In general, we need to create a threat model to simplify risks. The threat model generally checks the threats to components from multiple perspectives. stride is the practice of the threat model, including six types of threats. User identity fraud, tampering, credit, information leakage, denial of service, and privilege escalation.
In general, if the specific implementation is not strong enough, the risk analysis with built-in security considerations and a good security threat model is meaningless.
From object to Aspect
The object-oriented concept is good at splitting the system into components and describing processes with components. It is also good at processing component concerns. However, the cross-cutting concerns are not object-oriented. Cross-cutting concerns are those that affect multiple components of the system, such as logs, security, and exception handling. The main purpose of AOP orientation is to split the implementation of cross-cutting concerns and core concerns. The specific aspect is not described too much.
Related blogs:
- . Net enterprise-level application architecture design: Contemporary architects and Architectures
- . NET Enterprise Application Architecture Design-UML
- Design principles and models for. net enterprise-level application architecture design
- . NET Enterprise Application Architecture Design-Business Layer Design
- . Net enterprise-level application architecture design-service layer design
- . Net enterprise-level application architecture design-data access layer
- . Net enterprise-level application architecture design-Presentation Layer Design