preface
In my first two articles, I talked about a third approach to component extensibility, a new approach to the current standard component packaging and CV approach.
I will focus on this third route in this article.
An online demo of this article can be viewed here
Structured – React-hook project: Git address
—- The first two articles —-
Debate on front-end technology and front-end engineering
Are you still using the Redux bucket? How about a more lightweight and simpler structured hook?
The body of the
Let’s feel the problem of standard parts packaging and CV method through the scene
Ming is an ambitious front-end engineer who has only been in the business for a year. Although he has little experience, he has become the core figure of his team.
One day, Xiao Ming received a demand to develop a complex page, how complex (imagine here, you have encountered the most complex page), but it is not difficult to Xiao Ming, after all, he is a man with a coated open HHKB keyboard.
After a few days, Ming has finished his work, and the code might look like this
functionI am a complex component (){
// Omit 2000 lines of code here
}
Copy the code
After the test, it passed the test and was released online. Xiao Mingzhi was satisfied and also received the praise of the product xiao Mei.
Next to a few days later, a business group, the new products, in order to jump start the market, seize the opportunity, next to the position product wang (like xiao Ming like little beauty products), joined the little beauty in his product design for xiao Ming to do a few days ago the huge complex page, to quickly meet the needs of the business (rival) at the same time
Xiao Ming naturally saw through the rival’s tricks, and quickly put forward the idea of reusing the components he developed before in the requirements review. However, Xiao Wang’s shameless requirements to modify some UI and interaction in the page, and also to add some customized processes. Young Xiao Ming will not admit defeat.
I thought, “Just add a few more apis and parameters, and I’ll refine it.”
So a few days later, Ming wrote the following code
functionI am a massively complex reusable component (xiaoWangeDeConfig, xiaoMeiDeConfig){
let config = xiaoMeiDeConfig
if{config = xiaoWangDeConfig}// Omit 3000 lines of code here
}
Copy the code
Compared with the first time, Xiao Ming lost a lot of hair this time, and although there was no increase in requirements, the code increased from 2000 lines to 3000 lines due to various IF judgments. Fortunately, xiao Wang’s requirements were finally refined into config, and in order to meet the requirements of Goddess Xiao Mei, As the default config, Xiaoming happily looked at his components, secretly proud of the release of the test, everything went on as scheduled, Xiaoming got praise from xiaomei again, at the same time severely hit Xiaowang’s pride.
The frustration of Xiao Wang is very unhappy, so find the group of Daming (senior front-end Lao Bird, CV Da Fa thirty-third generation of the disciple)
Xiao Wang: Daming, do you think how can I raise requirements so that Xiao Ming’s components can’t be maintained? Overtime to baldness? Daming: That’s not easy. All you have to do is… Xiao Wang 😏 MMM MMM MMM
One week later, Xiao Wang sorted out the requirements again and went to Xiao Mei, saying that the business was developing rapidly, and now we needed to integrate the services of the three parties and try to build a business ecosystem quickly. Therefore, some new processes should be added to the hugely complicated component. Daming proposed that Xiao Ming provide some callback to add their own logic.
Small beauty asked Xiao Ming can do, the goddess asked which is not good, and Xiao Ming has always turned up his nose at CV big method, early see that more than 30 years old big clear, like to place qualifications, so a promise.
So according to Wang’s requirements, Xiao Ming modified the components again
functionI am a complex and dying component that can be reused and extended (xiaoWangBaDeConfig, xiaoMeiDeConfig){
let config = xiaoMeiDeConfig
if{config = xiaoWangBaDeConfig}// Omit 500 lines of code
if(config.callBack){
callBack()
}
// Omit 500 lines of code
if(config.callBack){
callBack()
}
// Omit 500 lines of code
if(config.callBack){
callBack()
}
// Omit 500 lines of code
if(config.callBack){
callBack()
}
// Omit 500 lines of code
if(config.callBack){
callBack()
}
// Omit 500 lines of code
if(config.callBack){
callBack()
}
// Omit 500 lines of code
if(config.callBack){
callBack()
}
}
Copy the code
After several all-nighters, Ming finally changed the requirement, this time averaging one callback for every 500 lines, so that he could perform a piece of logic. Although Ming had deep doubts about such an intrusive parameter, Daming promised
“Don’t worry, I just do the following, absolutely nothing!” 😏
Two red eyes of the small Ming energy is too busy to think, so raised test.
Test big strong continuous test 3 times this component, although the mood is agitated, but still patience test. This time he mentioned a few bugs
“Xiao Ming, the quality of this test is a little low. You have affected Mei’s original demand in several places. Please pay attention to it.”
Because of the general quality of the test, coupled with not as early as before, the United States did not praise Xiao Ming this time, xiao Ming is a little depressed after a hard week. But he does not know, the distant kanye Wang and Daming have been staring at him, showing a gloomy smile 😏
The breakdown of Xiaoming
After another month, Xiao Ming was always on the run, Xiao Wang and Daming always had demands, especially Daming, because of the introduction of various callback, every modification needs Xiao Ming to cooperate with the tune, from time to time can not run up to find Xiao Ming, even the needs of Xiao Mei are delayed, until the end of the month, Xiao Mei found Xiao Ming
“Xiao Ming, Xiao Wang’s new product business is doing well. The boss requires us to align the component you provided with their interaction. Please change it and remove our original interaction.
⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ small beauty to xiao Ming came as a thunderbolt ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️ ⚡ ️
Xiao Ming thought to himself, “I @#! @#, that component has been changed beyond recognition by me. Delete nearly 10,000 lines of code whenever you want. Even if I agree, big and strong will go crazy.”
“Oh right, your technology boss last meeting said you this component is very common, had better be to want to put forward to let other business also can reuse, time to grasp point tight, I value your 😁”
“What the…”
The following week Xiao Ming stayed up all night 007double, but the pain big strong was pulled back, finally caught up with the release date on the last day, but also lost the last few hair.
After the day, Ming because bald by the technology department as god, continue to maintain his huge huge complex components, because the amount of code is too large, Ming did not dare to reconstruct, kept to add parameters, not CV, although previously sniffed, but Ming found that CV can reduce a lot of his maintenance pain, Especially those who do not live long business, C to their own, they will not be so tired, there will not be a lot of problems. Balding at the same time he also lost the favor of small beauty, because small king white piao xiaoming’s resources, successfully quickly online a business, be promoted by the boss for new product leader, at the same time the business of small beauty under the jurisdiction, close water building platform first get month, add a head of beautiful hair, soon with small beauty together. Daming was also promoted to be the technical team leader because of his meritorious assistance, and continued to rely on CV DAFA to support various short-lived businesses.
The end of the whole
I didn’t actually make it up. Aside from the love triangle, most of the characters here are from my professional experience.
The HappyEnding of the whole script is based on the barbaric growth history of the Internet in the past 20 years. Because of the existence of a large number of short-lived businesses, front-end technology is difficult to achieve in software engineering, and a large number of front-end engineers are exhausted by these short-lived businesses. Both the ambitious young and the veteran end up as tools of the business, and the amount of code we write and the amount of business experience we accumulate is just as worthless as these short-lived businesses that are quickly being burned by hot money.
Let’s get back to the main point of this article.
Whether or not you’re personally familiar with the examples above, I think we can all agree on a few things about how components are packaged today. The main problem with existing encapsulation is that
- Because front-end components are nested based on a page structure, the cost of modifying the internal code of the component is proportional to the number of nesting layers of the component
- Each additional callback, hook, and parameter required to modify the component’s internal code in order to meet the requirements of the various open callback, hook, and parameter
The combination of the two, aggravated the expansion effect of the component, so the component is more difficult to use, the more difficult to use the more immovable.
In object-oriented software design, there is a core design principle of open and closed principle, closed to modification, open to expansion
In fact, inheritance polymorphic encapsulation in object-oriented languages is designed based on this principle. But obviously the front end is used
However, the component developed by JavaScript violates the principle of closing the modification. Object oriented is to solve the problem of software reuse, while open and close principle is more like the foundation of software reuse. We now use component extensions to do the opposite. When we encounter component extensions, we need to modify the internal code of the component. But what can we do?
JavaScript itself does not have a full class feature, and class-based languages such as Java have many problems being practiced in modern complex software, since the back end is no better than the front end. Once a class is inherited multiple times, it’s already written without knowing its last name, but at least the server doesn’t have to deal with logic and design conflicts.
So is there a way to technically implement the open close principle in the front-end domain without getting bogged down in Java’s complex class design architecture? If so, can we write components that are “really ‘easy to maintain and extend?”
The answer is Membrane Mode
Membrane Mode
I have mentioned Membrane Mode for many times in recent articles. Here I would like to explain the meaning of Membrane Mode. In fact, Membrane Mode is the integration of some language features, so as to realize the points I mentioned above
- Ability to write code that conforms to open and close principles
- Avoid complex inheritance systems
To achieve the above two objectives, Membrane Mode must be limited to
- Extensions to internal code are implemented by inheriting overload combinations without modifying the internal code
- There are two levels of restricted inheritance: father and son, and no grandchildren
To make the following example more persuasive, I will use structured- React-hook, a react Hook based state management framework that implements Membrane Mode, to write the example
Let’s start with one of the simplest Button components
A basic Button with a basic UI
import React from "react";
import createStore from "structured-react-hook";
function Button() {
return (
<div>
<button>I'm a button</button>
</div>
);
}
export default Button
Copy the code
Let’s add a toggle Loading copy that looks something like this
Here’s the code
import React from "react";
import createStore from "structured-react-hook";
function query(res) {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
resolve(res);
}, 1000);
});
}
const storeConfig = {
initState: {
loading: false.text: "Click on me to initiate a request."
},
controller: {
async onButtonClick() {
this.rc.setState({
loading: true.text: "In requesting server..."
});
const res = await query("Request completed");
this.rc.setState({
loading: false.text: res }); }}};const useButtonStore = createStore(storeConfig);
function Button() {
const store = useButtonStore();
return (
<div>
<button
disabled={store.state.loading}
onClick={store.controller.onButtonClick}
>
{store.state.text}
</button>
</div>
);
}
export default Button;
Copy the code
Here’s something to break Ming down
Daming said: we need to reuse this component, please give a callback when the request is completed, I want to add logic 😏
How does Membrane Mode solve this scenario
Membrane Mode uses the characteristics of AOP to cut in logic
// A separate file for Daming to modify
membrane-daming.js
const membrane = {
controller: {
async onButtonClick() {
await this.super.controller.onButtonClick();
alert("I'm Daming."); }}};Copy the code
Does Ming need to add a callback parameter to the Button component? The answer is no. Xiao Ming only needs to add the membrane reference provided by Daming to storeConifg
import membrane from 'membrane-daming'
const storeConfig = {
initState: {
loading: false.text: "Click on me to initiate a request."
},
controller: {
async onButtonClick() {
this.rc.setState({
loading: true.text: "In requesting server..."
});
const res = await query("Request completed");
this.rc.setState({
loading: false.text: res
});
}
},
membrane
};
Copy the code
This is what the extension looks like
Eye Chou Xiaoming solved daoming’s difficulties smoothly, the Daoming that regards senior old bird as a senior will not give up again, he of sharp eye discovered a problem
“!!!!! Wait, I was wrong, I’m going to pop up and ask the user if they want to continue requesting 😏 before the request logic triggers.”
How does Membrane Mode solve this problem
The answer is to replace special logic with structural substitution.
What is structural substitution?
I remember Google was planning to release a phone called a modular phone where users could replace the modules as long as the phone supported them. In the construction industry, many buildings can be retrofitted without destroying the foundation, just replacing the structure. What about the code?
Can’t change your code at all in the face of modification shutdown? Obviously not. In the face of modification closing, my understanding is not to modify your existing code to implement the extension, using the thinking of functional programming, we just need to program a large function to several small functions, and allow the extender to replace the function, so that we protect our own code, While satisfying various fine-grained scaling requirements, let’s go back to the above scenario
Hearing Daming’s request, Xiao Ming reconstructed his code structure without thinking, but still did not add any parameters, and did not give Daming the opportunity to invade his code
So Ming sliced up his own code, provided a new structure, and then asked Daming to extend the effect he wanted, which looked like this
The following code
Daming’s file
const membrane = {
service: {
beforeQuery() {
const res = window.confirm("Do I really need to make a request? (Ming)");
returnres; }},controller: {
async onButtonClick() {
const res = this.service.beforeQuery();
if (res) {
this.super.service.beforeQuery();
this.super.service.query(); }}}};Copy the code
Xiao Ming’s file
const storeConfig = {
initState: {
loading: false.text: "Click on me to initiate a request."
},
service: {
beforeQuery() {
this.rc.setState({
loading: true.text: "In requesting server..."
});
},
async query() {
const res = await query("Request completed");
this.rc.setState({
loading: false.text: res }); }},controller: {
async onButtonClick() {
this.service.beforeQuery();
this.service.query();
}
},
membrane
};
Copy the code
The two modules still only maintain the connection between memberships, while Daming and Xiaoming independently maintain their own codes.
The point is that Ming did not open any parameters for Daming from beginning to end, including callback, params and so on. What Ming needed to do was to cut, cut and cut again, just like function, to atomize his own code and avoid code intrusion and code expansion caused by external extension.
But will Daming give up? What vitriolic new challenges will Daming present, and how will Xiao Ming respond
See the next breakdown at………….
The latter
Membrane Mode absorbs some valuable features from past programming paradigms, providing single-inheritance based function overloading, inheritance, encapsulation, and AOP using structure substitution instead of the usual arguments and API extension ideas. If you are interested in this article and in Membrane Mode, please contact me. Welcome to communicate with me at 😏