1

Some students may think that the front-end is relatively simple and does not require an architecture, or because the front-end interaction details are complicated and it is difficult to unify and abstract, so there is no way to design the architecture. This understanding is one-sided. Although some front-end projects are piled up without careful consideration of the architecture, this does not mean that architecture design is not required. Any business program can implement functions by stacking code, but the maintainability and scalability behind it are naturally very different.

Why should front-end projects also consider architecture design? There are several reasons:

  • From the point of view of necessity , the front-end and back-end applications all run on the computer. The computer has a clear architecture design and layering from the hardware to the operating system, and then to the upper-level library. The application program, as a part of the top layer, is also embedded in the entire large architecture. Tori's.
  • From a feasibility point of view , although interactions are numerous and complex, this does not constitute a reason for not requiring architectural design. For computer basic design, it is also faced with a variety of input devices and output devices, and then the abstraction of standard input and output generated, so the front end should also be the same.
  • From a broad perspective , most of the common conventions and models have long since settled, such as programming languages, and the front-end framework itself is part of the business architecture. Even writing "Hello World" with React uses a data-driven design concept.

In terms of necessity , although the operating system and various basic libraries shield the underlying implementation, so that the business can only care about business logic, which greatly liberates productivity, an application must be run only by the coordination of the underlying operating system and the business layer code. The application program has a set of logical hierarchical architecture design. If there is no good architecture design at the business layer, the technical abstraction will be a mess. It is difficult to imagine that the overall operating environment formed in this way is healthy.

The architecture design of the business module should be similar to the architecture design of the computer base. Starting from the demand analysis, design the business sub-modules, and define the responsibilities of these sub-modules and the relationship between the sub-modules. The design of sub-modules depends on the characteristics of the business, and the layering between sub-modules depends on the expansion capability of the business.

For example, when designing a drawing software, as long as the component subsystem and the layout subsystem are required, they are independent of each other and can be seamlessly combined. For BI software, the concepts of screening linkage and general data query are added, so the corresponding sub-modules of screening linkage model, data model, and graphic grammar will be added, and they will be layered up and down according to their functional relationships:

<img width=400 src="https://s1.ax1x.com/2022/08/21/vyrS0K.png">

If the layering is clear and accurate, it can be seen that the two upper layers of the business have the same abstraction, that is, the uppermost layer is the combination of components and layout, while the filtering linkage and data query, as well as the mapping function from data model to graphical element relationship They are all additional items, and their removal will not affect the operation of the system. If it is not designed in this way, the similarities and differences between the systems may not be clear, resulting in functional coupling. To maintain a large system, it may be necessary to always relate to the mutual influence of each module. Such a system is neither clear nor sufficient. It is scalable, the key is to maintain its understanding and the cost is also high.

From the feasibility point of view , the front-end is characterized by a lot of contacts input by the user, but this does not prevent us from abstracting the standard input interface. For example, if the user clicks a button or the input box is input, the keyboard shortcut is also an input method, and the URL parameters are also An input method, and the form configuration before the business is also an input method. If there are many input methods, the abstraction of the standard input becomes important, so that the actual complexity of the business code will not really expand to the complexity of the user. so high.

Not only are there many input contacts, but there are also many functional combinations of the front-end system, such as graphics drawing software, where any number of components can be placed on the canvas, each component has any number of configurations, and components can also affect each other. This kind of system is an open system. It is easy for users to try out combinations of functions that developers have never thought of. Sometimes developers are amazed that these new combinations can work together! Users will sigh at the powerful capabilities of the software, but developers cannot really combine these functions one by one to resolve conflicts, and must ensure the stability of function combinations through reasonable layered abstraction.

In fact, this kind of challenge is also a problem faced by computers. How to design a computer with a general architecture so that any developer software can run on it, and the software can be independent of each other or call each other. The system is not prone to bugs. From this point of view, the underlying architecture design of the computer is of reference significance for the front-end architecture design. Generally speaking, the computer solves the problem of computing everything through the three layers of hardware, operating system, and software.

The von Neumann system solves the problem at the hardware level. In order to ensure the scalability of the software layer, the three basic capabilities of computing, storage, and expansion are solved through the abstraction of CPU, storage, and input and output devices. In terms of subdivision, the CPU only supports three basic capabilities: mathematical calculation, conditional control, and sub-functions. This makes the underlying design of the computer not only stable, but also enumerable for design factors, and has a strong ability to expand.

The same is true for the operating system. It does not need to know how the software is executed. It only needs to provide a safe operating environment for the software, so that the software will not be interfered by other software; it provides some basic paradigms to unify the behavior of the software, such as a multi-window system. , to prevent the software from drawing in an area at the same time and interacting with each other; provide some basic system call encapsulation to the upper language for secondary encapsulation, and considering that these system call encapsulation may be expanded with demand, the dynamic link library method is adopted implement, and so on. In order to make its functions stable and enumerable, the operating system defines a clear boundary between itself and the software. No matter how the software is expanded, the operating system does not need to be expanded.

Going back to the front-end business, if you want to ensure the clarity and maintainability of a complex drawing software code, you need to start from the bottom stable module and build the dependencies between modules step by step. Only in this way can the logic in the module be enumerated. For example, modules and modules can only be boldly combined, and each design its own expansion point, so that the entire system finally has powerful expansion capabilities, but each sub-module is a simple, clear, enumerable and testable code logic.

Taking the BI system as an example, it is divided into four subsystems: component, filter, layout, and data model:

  • For the component system, any component implementation can be accessed, which enables this BI system to display not only reports, but also ordinary buttons and even forms, and can build any data product, or build any website, and expand its capabilities. Where to go is entirely up to the business.
  • For the screening system, any component can be associated, not necessarily from a filter to a chart, but also from a chart to a chart, which supports chart linkage. Not only BI linkage scenarios, but even a form linkage can reuse this filtering capability, making the entire system unified and simple.
  • For the layout system, it does not care what the components in the layout are and what related capabilities they have, as long as the layout is done well. In this way, the canvas system can be easily extended to any scene, such as productivity tools, dashboards, ppts or large screens, without affecting other systems.
  • For the data model system, it undertakes the process of data configuration to SQL query, and finally mapping to the graphical channel display. It itself is an abstract implementation of the statistical chart type in the component system, so although the logic is complex, it does not affect other Subsystem design.

From a broad perspective , front-end business code has long been in a series of architectural layers, that is, programming languages and front-end frameworks. Programming languages and front-end frameworks will come with some design patterns to reduce the communication cost caused by mixed code paradigms. In fact, the architecture design itself also needs to solve the problem of code consistency, so these contents are part of the architecture design.

The data-driven feature brought by the front-end framework itself largely solves the maintainability of front-end code in complex applications, and greatly reduces the complexity of process code. The React or Vue framework itself also acts like an operating system, that is, it defines the specifications of upper-level components (software specifications), smoothes browser differences (hardware differences) for component rendering and event response, and provides component rendering scheduling functions (software scheduling). ). It also provides variable transfer between components (process communication), so that the communication between components conforms to a unified interface.

But it is not necessary to design each component by analogy to the process, that is to say, the components do not all work through communication. A more appropriate analog granularity is module, which abstracts a large module into a component, and the modules do not depend on each other, and communicate with each other through data communication. Small-grained components are made into state-independent components. Pay attention to keeping the interfaces of components with similar functions consistent as much as possible, so that you can experience the benefits of similar polymorphism.

So having said that, following the code specifications of the front-end framework is not optional. The business architecture design has already started from the programming language and the front-end framework. If a component does not follow the best practices of the framework, it cannot participate. In the upper-level business architecture planning, it may eventually lead to project confusion or no architecture at all. Therefore, paying attention to architecture design starts from code specification.

So the front-end architecture design is necessary, so how to do the front-end architecture design? This topic is too large. This time, I will borrow some inspiration from the operating system, and first talk about the understanding of layering and abstraction.

no absolute stratification

Layering is the focus of architecture design, but the position of a module in the layering may change with business iterations. Analogy to the operating system to give two examples:

Voice input is now provided by each software itself, and the voice recognition and NLP capabilities behind it may come from the AI mid-stage of major companies, or some cloud services that provide AI capabilities. However, when the voice input capability matures, it is likely to become the built-in capability of the operating system, because both voice input and keyboard input are standard input, but the voice input is more difficult, and the operating system is difficult to build in the short term, so it is currently developing in various upper-layer applications.

The coroutine of Go language is implemented in the programming language layer, but its target thread is implemented in the operating system layer, the coroutine runs in the user mode, and the thread runs in the kernel mode. But if the operating system provides more efficient threads one day, and the memory usage also adopts the logic of dynamic increase, maybe the coroutine is not so necessary.

It stands to reason that voice input is a part of standard input and should be implemented in the general input layer of the operating system. Coroutines are also part of multitasking and should be implemented in the multitasking layer of the operating system, but they are all now in the upper layer. Some are at the programming language layer, and some are at the business service layer. The reason for these accidents is that the requirements of the general-purpose input and output layer and the multitasking layer are not as stable as imagined. The upper layer is realized.

Of course, we should also note that even if these extension points are implemented in the upper layer, they do not have a particularly intrusive impact on software engineers, such as goroutines. Programmers do not touch the API provided by the operating system, so the programming language The expansion of the capabilities of the operating system by the layer is transparent to the programmer; the voice input has a little impact. If it is implemented by the operating system, it may become an event structure consistent with the keyboard output, but it is implemented by the business layer. There are countless API formats, and business processes may be more complex, such as adding authentication.

From the computer operating system example we can learn two things:

  1. From the perspective of layered rationality, the input is further abstracted and integrated. For example, encapsulating speech recognition into a standard input event makes it logically a standard input layer.
  2. The design of business architecture will inevitably encounter scenarios where layering does not meet business scalability.

The difference between business layering and hardware and operating systems is that in business layering, almost all layers are easy to modify and expand. Therefore, if you encounter an unreasonable layered design, it is best to move it to the layer it should belong to. The reason why the operating system and hardware layers are inconvenient to expand at will is that the frequency of version updates does not match the frequency of software updates.

At the same time, it is also necessary to realize that layering requires an evolutionary process. It may be better to wait for the new module to stabilize and then move to the layer where it belongs, because moving from the upper layer to the bottom layer means that more modules are shared and used, just like we will not easily Just like building a function provided by a package in the software layer into a programming language, it will not arbitrarily build a function implemented by a programming language into a built-in system call of the operating system.

An example in the front-end field is that if a platform building project already has a set of component meta-information descriptions, it is best to let it run in the business code for a period of time to observe which attributes defined by the meta-information are missing and which are It is unnecessary. After the business is stable for a period of time, the set of meta-information runtime codes can be extracted into a general package and provided to the business or even other businesses. But even if this ability is deposited in a general package, it does not mean that it can never be iterated. The multitasking management of the operating system is challenged by coroutines, not to mention the ability of an abstract package at the front end? So be careful about abstraction, but you must also dare to question and challenge after abstraction.

no absolute abstraction

Abstraction granularity is always an architectural design challenge.

Computers understand everything as data. The result of the calculation is data, and the code that executes the program is also the data, so as long as the CPU focuses on the calculation of the data, plus storage and input and output, everything can be done. Think about the greatness of this abstraction: all programs are ultimately these three concepts to the computer, and the CPU does not need to care about any business implications when computing, which also allows it to compute any business.

Another controversial abstraction is the abstraction of Unix everything is a file, which abstracts the management of files, processes, threads, sockets, etc. as file APIs, and all have specific "file paths", such as you can even pass /proc Access to the process folder, ls You can see all running processes. Of course, a process is not a file, this just illustrates an abstract philosophy of Unix, that is, "file" itself is an abstraction, development and everything can be understood in the way of understanding files, which brings a huge reduction in the cost of understanding, and also makes Many code patterns can be unconcerned about specific resource types. But the controversial point of this is that not all resources are suitable for abstracting into files, such as the display in input and output. As a carrier that presents colorful pixels, it is really difficult to use the file system to describe it uniformly.

Computer design and operating system design have given us obvious inspiration, that is, everything that can be abstracted should be as abstract as possible, so as to improve the stability of each module of the system. However, from the perspective of the abstraction that everything is a file in Unix, sometimes the technical abstraction is inevitably limited by the business requirements at that time. When the types of input and output devices increase, this extreme abstraction may not always be suitable. But always believe in abstraction, because if all resources can be described by file abstraction, and there is no inconvenience to use, why create other abstractions? Do not add entities unless necessary.

For example, can the screening, linkage, and drill-down scenarios of BI scenarios be abstracted into linkages between components? If a set of standard linkage design can solve these three scenarios, then there is no need to introduce a separate concept for a specific scenario. From the original scenario, whether filtering, linkage or drill-down scenarios are to modify the fetching parameters of components to change the query conditions, we can abstract a specification of linkage between components, so that it can drive the change of fetching parameters. However, future requirements may introduce more possibilities, such as triggering some additional additional analysis queries during screening. At this time, the previous abstraction has been challenged. We need to balance the benefits of maintaining uniformity and the general interface is not suitable for special scenarios. to balance the costs.

There are countless ways of abstraction. Which one is better depends on how the business changes. You don’t need to worry too much about the perfect abstraction. Even the most basic abstraction of Unix everything is a file is controversial, and the stability of business abstraction will definitely be worse. More needs to be adjusted as needs change.

Summarize

Starting from the architecture design of computers and operating systems, we discussed the necessity of front-end architecture design, and analyzed the considerations in architecture design from the perspectives of layering and abstraction. I hope that when you encounter uncertain problems in architecture design, You can go down to get some inspiration or support with the architectural design of your computer.

The discussion address is: Intensive Reading "Understanding of Front-end Architecture - Layering and Abstraction" Issue #436 dt-fe/weekly

If you'd like to join the discussion, click here , there are new topics every week, with a weekend or Monday release. Front-end intensive reading - help you filter reliable content.

Follow Front-end Intensive Reading WeChat Official Account

<img width=200 src="https://img.alicdn.com/tfs/TB165W0MCzqK1RjSZFLXXcn2XXa-258-258.jpg">

Copyright notice: Free to reprint - non-commercial - non-derivative - keep attribution ( Creative Commons 3.0 license )

黄子毅
7k 声望9.5k 粉丝

« 上一篇
精读《pnpm》