Have You Learned the Simple Principles of Architectural Design?

2024.09.09

The declaration of the principle of simplicity is: "Simple is better than complex."

Because software architecture and architectural architecture are superficially similar, we tend to subconsciously transfer our aesthetic concepts of architecture to software architecture. For the software architecture we build ourselves, we expect it to be as grand, exquisite, artistic, and luxurious as famous buildings... In short, it must not appear shabby or simple.

Team pressure sometimes pushes us toward complexity, intentionally or unintentionally. Because when most people evaluate the level of a solution, complexity is an important reference indicator. For example, if a heartbeat mechanism is used to implement a master-slave solution, people may think it is too simple. However, if ZooKeeper is introduced to make master-slave decisions, many people may think that this solution is more "high-end". After all, ZooKeeper uses the ZAB protocol, and the ZAB protocol itself is very complex. In fact, there are very few people who truly understand the ZAB protocol, but this does not prevent us from knowing that the ZAB protocol is excellent.

The complexity of the software field is reflected in two aspects

Systems with complex structures usually have two characteristics: first, there are a large number of components that make up the system; second, the relationships between these components are extremely complex.

However, there is a first problem with structural complexity. The more components there are, the greater the probability that one of them will fail and cause the system to fail. This probability can be calculated. Assuming that the failure rate of a component is 10% (that is, it is unavailable 10% of the time), the availability of a system composed of 3 components is (1 - 10%) × (1 - 10%) × (1 - 10%) = 72.9%, while the availability of a system composed of 5 components is (1 - 10%) × (1 - 10%) × (1 - 10%) × (1 - 10%) × (1 - 10%) = 59%, a difference of 13% in availability.

There is a second problem with structural complexity. Changes to a component will affect all components associated with it, and these affected components will continue to recursively affect more components. This problem will affect the development efficiency of the entire system, because once the change involves an external system, it is necessary to coordinate all parties to jointly conduct solution evaluation, resource coordination, and online cooperation.

There is a third problem with structural complexity. It is always more difficult to locate problems in complex systems than in simple systems. First, because there are so many components, each component is suspected of having problems, so they need to be checked one by one; second, the relationships between components are complex, and the component that shows a fault may not be the root cause of the real problem.

The second aspect is reflected in the complexity of logic

When we realize the complexity of the structure, our first reaction may be to "reduce the number of components". After all, the fewer the number of components, the simpler the system structure. The simplest structure is undoubtedly that the entire system has only one component, that is, the system itself, and all functions and logic are implemented in this one component.

Unfortunately, this is not feasible. The reason is that in addition to structural complexity, there is also logical complexity. If the logic of a component is too complex, it will also cause various problems.

A typical feature of logically complex components is that a single component assumes too many functions. Taking e-commerce business as an example, common functions include product management, product search, product display, order management, user management, payment, delivery, customer service, etc. If all these functions are implemented in one component, it is a typical logical complexity.

Assuming that Taobao now implements all these functions in a single component, we can imagine this terrifying scenario: the system will be very large, with millions or tens of millions of code, and it will take 30 minutes to "clone" a code. Dozens or hundreds of people maintain this set of code, and a "rookie" accidentally changes a line of code, which may cause the entire site to crash. Demands are coming in like snowflakes. In order to cope with them, dozens of code branches will be opened, and then various branches will be merged and covered. Product, R&D, testing, and project management will hold meetings to discuss version plans, coordinate resources, and resolve conflicts. There are too many versions, and dozens of versions must be launched every day. The system must be restarted every hour. If there is a failure in the online operation, dozens of people will rush to locate and handle it. A small dark room cannot accommodate everyone, and the entire office area will be in chaos.

In short, no one can tolerate such a scenario. Another typical feature of components with complex functions is the use of complex algorithms. The main problem caused by complex algorithms is that they are difficult to understand, difficult to implement, difficult to modify, and difficult to solve problems quickly.