preface

“What can I hide now?” cried the feng Ping in his ears. Looking up to the sky a clear noise, oblique line and front, longjian crosscut direct strike, swift and clinking, not to five or six strokes, the sword potential has issued faint wind. He drew his sword faster and faster, and the sound of the wind was getting louder and louder, and the strength of the edge of the sword was gradually expanding. The onlookers only felt the cold, and their faces and hands were pained by the strong wind. They could not help falling back, and the circle around the fighting two people was gradually expanding to four or five cubits. A Taoist priest of The Taishan school said beside him, “The disciples of the Air school have high sword skills, while the masters of the Jian school have strong internal forces. How on earth did this happen? Huashan school’s airbenders and jian benders are playing upside down, aren’t they?

“Swordsman’s river’s lake” in “sword zong residual evil” seal injustice wants to rely on to have Songshan to send support originally, seized the throne of hua Shan at one fell swoop. Can play for a long time on the sword can not take advantage of, finally can only use “wind quick sword”, in an attempt to win the internal force. Visible, any brilliant kung fu if no internal work heart method complementary, is also futile.

Back to the front end, today’s front end technology stack is just like the river’s lake in the wuxia novel, each faction into one of its own, it can be said that “a hundred flowers blossom”, “a hundred schools of thought contend”.

Here React, Vue, AngularJS, JQuery none of them are unified. The “upstarts”, Flux, Redux, Mobx, have been busy fighting over who is the biggest data flow framework. As soon as Native End RN went out of business, Weex became “I’m the Everywhere”. Even within the controversial GraphQL, Apollo and Relay still have to be pinched.

I often hear front end engineers around me complain that I haven’t read the XXX new version document released last week. Today, YYY company released a new framework. Which one should I learn first? In fact, no matter what kind of framework which technology is to solve the actual business needs of means, methods, and martial arts in the martial arts of each faction is the same, each has its own strengths, each has its own unique.

When we study technology, in addition to understanding the specific use method, we also need to master the design concept and engineering thought behind the technology, which is the basis of our technology selection, the foundation of architecture design, and the soul of software system. This is just like the “inner kung fu heart method” in the martial arts to urge fist, foot, knife and gun, one move one type, tiger tiger born wind, even if there is a great enemy, is also cool and poised.

Next, we will talk about three engineering ideas, which are: “Open closed principle”, “functional programming” and “information system”, the three engineering ideas are widely used in the back-end development, and is easy to ignore many current front-end technical framework and applied to the three kinds of thoughts, the following specific case analysis, hope to be able to help us deepen the understanding of the technology itself.

The open closed principle

When it comes to object-oriented design, most people think of “23 design patterns.” Design patterns represent the best practices summarized in the business scenario. They are practices, and above them are the more important “SOLID” principles:

  • The Single Responsibility Principle
  • The Open Closed Principle
  • The Liskov Substitution Principle
  • The Dependency Inversion Principle
  • The Interface Segregation Principle

SOLID’s five principles start with the ultimate goal of software engineering: “High cohesion, low coupling.” The most widely used principle in back-end development is the dependency inversion principle, which is associated with about 5-6 design patterns. As shown in the figure below:

The figure above can also be understood as a gradual evolution from abstract concepts to concrete practices.

In the front-end technology framework, the most commonly used principle is the “open closed principle”. Let’s take a look at how this principle is defined:

A software artifact should be open for extension but closed for modification.

Software systems should be open to extension, but closed to modification. Here’s a simple example to illustrate the open closed principle, to help you understand the concept:

public abstract class Shape { public abstract double Area(); } public class Rectangle: Shape { public double Width { get; set; } public double Height { get; set; } public override double Area() { return Width*Height' } } public class Circle: Shape { public double Radius { get; set} public override double Area() { return Radius*Radius*PI; } } public double Area(Shape [] shapes) { doubel area = 0; foreach (var shape in shapes) { area += shape.Area(); } return area; }Copy the code

In the example above, no matter how the scenario is extended, the Area function does not need to be modified. Each Shape class implements Area calculation by inherits the interface and polymorphism.

To sum up the open closed principle is: the core logic of the software system should not be changed easily, otherwise it will destroy the stability of the system and increase the test cost. We should establish appropriate abstractions and unify interfaces, and when the business needs to expand, we can do so by adding entity classes.

Next, let’s look at an application of the “open closed principle” to the front end framework: the Form component in the Ant Design component library.

Unlike other components, the Form component does not have a specific shape. It is more like a container, providing access standards, validation, Form submission, and other functions. One of the items in the draw form looks like this:

<FormItem>
  {getFieldDecorator('userName', {
     rules: [{ required: true.message: 'Please input your username! '}]}) (<Input prefix={<Icon type="user" style={{ color: 'rgba(0.0.0.25.) '}} / >}
		placeholder="Username" />
   )}
</FormItem>
Copy the code

The Ant Design component library already provides almost all of the common form components, such as: Select, Checkbox, Radio, Cascader, etc., but in actual business, we still need to design business-related Form items. Form meets this technical requirement through unified component interface, and the specific specifications are as follows:

Custom or third-party Form controls can also be used with the Form component. As long as the component follows the following convention:

  1. Provide the controlled property value or another property with the same name as the value of valuePropName.
  2. Provides an event with the same name as the onChange event or the value of the trigger.
  3. It cannot be a functional component.

Concrete example

This is a typical example of the “open closed principle,” where the Form core logic (validation, submission, etc.) remains unchanged and is encapsulated in the Form component. Custom Form items only need to meet the three requirements mentioned above to smoothly plug into the Form component and fit in with the Ant Design native component.

The Form component in Ant Design perfectly provides a unified solution for form-type pages with such a simple Design.

Functional programming

With the emergence of ai, blockchain, AR, VR, new retail and other business scenarios, product interface interaction is becoming more and more complex, which puts forward higher requirements for modern front-end developers. How to develop high complexity pages quickly, correctly and efficiently is the most important problem to be solved in the front-end technology.

Functional programming (FP) is beginning to dominate the front-end technology circle with its high reusability, testability, and robustness and simplicity, and we are seeing more and more front-end frameworks with FP as their core design criteria.

Let’s first briefly introduce FP. The characteristics of functional programming mainly include the following aspects:

  • The function is “first class citizen”
  • Modularity and combination
  • Reference transparent
  • Avoiding state changes
  • Avoiding shared states

Unlike Java, C/C++ and other languages, functions in JS can be passed as parameters and return values, so they are inherently first-class citizens. The four characteristics of modularity, composition, reference transparency, avoiding state changes, and avoiding shared state all need to be implemented through specific code patterns. Here are two small examples:

Find the first four non-numeric characters in the string?

The style of FP
var words = [], count = 0;
var text = str.split(' '); 
for (var i = 0; couont < 4, i < text.length; i++) {   
  if(! text[i].match(/ [0-9])) { words = words.concat(text[i]); count++; }}Copy the code
FP style
var words = str.split(' ').filter(function(x){
  return(! x.match(/ [1-9] + /))}).slice(0.4);
Copy the code

The second section of code uses js array methods filter and slice, remove the for loop, the code is more concise and smooth. When writing specific business code, “modularity, composition” is the most commonly used FP technology, but also the most important means to achieve functionality.

Do we add, multiply, and phase all the elements of the array?

The style of FP
function plus(array) {
  var res = array[0];
  for (let i = 1; i < array.length; i++) { res += array[i]; }}function mul(array) {
  var res = array[0];
  for (let i = 1; i < array.length; i++) { res *= array[i]; }}function and (array) {
  var res = array[0];
  for (let i = 1; i < array.length; i++) {
    res = res & array[i];
  }
}

plus(array);
mul(array);
and(array);
Copy the code
FP style
var ops = { 
  "plus": (x,y) = >x+y,
  "mul" : (x,y) = >x*y,
  "and" : (x,y) = >x&y
}

function operation(op, array) {
  return array.slice(1).reduce(ops[op], array[0]);
} 

operation("plus", array);
operation("mul",  array);
operation("and",  array); 
Copy the code

In the latter code, the reduce function is used instead of the for loop, and the numerical computation is extracted as a module. When a new computation type is available, the computation needs to be defined only in the OPS object. Here is the embodiment of FP “modular, combination” characteristics. In the FP-style, we are used to cutting complex logic into small modules, combining these modules to achieve new business functions, and reusing existing modules as much as possible when new requirements come in. FP code has a distinct advantage over OOD in terms of reusability.

FP ideas in React

In React framework, when the user’s UI or API operation returns changes the data, React immediately performs virtual DOM diff calculation to get dom modification instructions, and then applies modification instructions to DOM elements to get the latest HTML interface, as shown in the figure below:

It is not difficult to find that React is actually a mapping of application data to UI. Different data will map different STYLES of UI interface. We can get the following expression:

Yes, React is a function at heart, and it’s a “reference-transparent” function that meets FP’s requirements. The so-called “reference transparency” means that the output of a function depends only on the function parameters and is not affected by any external environment. Such functions are teachable and very easy to combine.

Under React, any component can be made up of smaller components, each of which is concerned only with its own input, constantly receiving new data and producing new UI. The “high order components” commonly used in the React framework can be seen as a combination pattern of reference transparent functions.

We usually need to weigh the React in the specific business component reusability and development experience, if the component is split is too thin, is reusability increases, but the number of files increases, the corresponding document and communication cost will increase, and it is also a FP in practice often to the point, namely reusability boost after the additional cost of development.

Message mechanism

Message mechanism is a widely used engineering idea in software engineering. The observer pattern in “design pattern”, the underlying Windows operating system, the ApplicationListener module in the Spring framework, and function calls in the Objective-C language are all driven by the message mechanism.

The biggest benefit of using message mechanism is that it can achieve the security decoupling between business modules, and the modules can cooperate by sending messages. Let’s first take an example of back-end development. The following figure is a simple modeling diagram of predetermined system without using message mechanism:

In the absence of a message mechanism, the user module needs to know the existence of the order module and make an interface call to the server. Similarly, the order module needs to make an interface call to the payment module. In this design, the modules are coupled.

Let’s look at the message mechanism again:

In the figure above, whether a customer places an order, pays, or orders, the message is delivered in the form of a message. Each module sends a message to a message handler and listens for messages sent back by the message handler. In this mode, modules are completely unaware of the existence of other modules and are thoroughly decoupled.

In front end business development, we often use the EventEmitter library for messaging. For example, there are two areas on the page, one is rendered with React frame and the other is rendered with D3. When the two areas need data synchronization, the message mechanism can be used for communication to ensure the overall consistency of the page data.

If you have components in your business that have different life cycles, it is recommended to use a message mechanism to manage them. Not only does this remove coupling, but the code for the logical relationships is also concentrated in one file, improving cohesion.

An add-on to using messaging mechanisms is middleware, which can be customized for messages, with some common logic in the middle to make the business code more refined.

In the Redux framework, any data interaction needs to be converted into an action. The action will trigger the Reducer and related Middleware to process the action and change the data. Finally, it is synchronized to the UI of the page, as shown in the figure below:

The pros and cons of using Redux are well discussed in various communities and will not be covered in this article.

conclusion

“Open and close principle”, “functional programming” and “message mechanism” are three important thinking methods in software engineering. They are like three sets of internal formulas. Only by mastering them can we understand the technical framework itself more deeply and give full play to the maximum power of the technical framework.

When I write here, I suddenly think of a passage in Tian Long Ba Bu:

Seeing others retreat, Qiao Feng suddenly thought of a move, and called out a punch, a move to “rush the battle to cut the general”, is also “Tai Zu long fist” in the move. This move is not only natural and easy, but also soft and soft in strength. This move shows the perfection of martial arts that a martial arts master hopes to achieve all his life.

A set of ordinary “Taizu changquan” in the hands of Qiao Feng can have such a look!

How many years later, whenever people talk about jin Yong, talk about the world of the martial arts, must be with relish to aftertaste, talk about the zhuxian village in this shock.

reference

  • Functional Programming in JavaScript — Dan Mantyla
  • Functional JavaScript: Introducing Functional Programming with Underscore — Michael Fogus
  • Clean Architecture — Robert C. Martin
  • reactjs.org
  • Ant – design. Gitee. IO/docs/react /…
  • redux.js.org/
  • redux-saga.js.org/
  • The Swordsman — Jin Yong
  • Tian Long Ba Bu — Jin Yong

The article can be reproduced at will, but please keep the original link. If you are passionate enough to join ES2049 Studio, please send your resume to caijun.hcj(at)alibaba-inc.com.