当前位置:网站首页>Alchemy (7): how to solve problems? Only reconstruction
Alchemy (7): how to solve problems? Only reconstruction
2022-06-28 00:19:00 【Phantom grey Dragon】

A lot of times , Sort through the code , Write the logic correctly , Straighten out dependencies ,BUG It's gone . One Bugly Legacy systems , Only thorough refactoring , Let the program be in 「 Good structure 」 state , Can be developed normally 、 Maintain and release versions . There is an essential problem , Is to let the code realize 「 High cohesion 、 Low coupling 」. Here are my refactoring notes .
work
I found the programming habits I used to take for granted , I wouldn't have written this messy coupling problem in the first place , So for a long time, I didn't feel that I should pay attention to writing code 「 High cohesion 、 Low coupling 」 Problem. . But this refactoring , Let me see what the spaghetti code is all about , But to take them apart , Step by step decoupling , Rewrite the code to 「 normal 」, I just 「 Feeling 」 To write code, you need 「 High cohesion 、 Low coupling 」 This matter , Many people need to learn and practice .
This refactoring proves once again 「 Global variables are the root of all evil 」, This man uses JavaScript Wrote a lot of classes , But what? , Each module returns one of this class 「 False single case 」, Further 「 Up 」「 Down 」, This false singleton is used in both the upper and lower layers , This leads to severe internal coupling on both sides 「 Class 」, This is equivalent to using a bunch of global variables directly . What's worse is , The member variables of these classes are directly exposed , Assign values everywhere , Expose all variables to 「 Without any encapsulation and protection 」 Under the 「 To modify at will 」.
I've been refactoring layer by layer these days :
- Uncouple in both directions , Between layers can only be
A<----B<---C<----DThis one-way dependency , Instead of relying on each other . Between layers in the program , One way dependency should be achieved , Can make the process clear , The structure is reasonable . - All variables are modified 「 encapsulation 」 Inside the class , All through the method to modify . On this basis , Modification of internal variables , Protect the internal state machine .
- carefully 、 Thoroughly clean up several important finite state machines (Finite State Machine), Draw the complete state transition diagram of state transition , There must be enterState Conversion method protection , Any error conversion will directly report an error . I think this is a direct reflection 「 Programming 」 Where is it , Do not understand finite state machine , It's not really programming . I see a lot of defining a bunch of States , But there is code that can jump between states , It's all like this Bugly The root of .
- Shrink a point where the class state is modified . A class defines a set of methods and properties , It should only be used in certain situations , All the places where this class is used , If you don't try to control it in a narrow range , Then the state modification is spreading , These dispersions not only make changes in state difficult to understand , It's not good for maintenance . Shrink the range step by step , according to 「 The correlation 」 Gradual analysis , What logic should be centralized in one place .
- Logic in functions , It shouldn't be a bunch of code that doesn't know what to do . Instead, it should be composed of a set of function calls that can be seen clearly at a glance , If not , Then you need to refactor this part of the logic , Let them form a suitable... In the right place , Function specific functions .
- Separate classes from different processes to different folders . Each process should only use classes in its own process , otherwise , You will encounter things like 「 I have clearly modified this variable , Why is it wrong 」 The problem of , Because what you modify and what you read are variables of two different processes , Although it looks like 「 Same class 」, If you have multithreaded code , It's similar . Specify which process each class belongs to . Physically separate them with meaningful folders . Each class should only be used by one process , Unless it is a stateless tool class . This further demonstrates that you should not use global variables , carelessly , You use it in two processes 「 The same variable 」 Of the two processes . Don't give yourself the chance to create this confusion .
- How to release
A<--->BThis kind of coupling ? Even though I was JavaScript Write the code , I still think about when to use 「 Interface 」, When to use 「 function 」 To decouple the problem . For many years , Based on object-oriented design patterns , Are telling you to face the interface to decouple , Is it true ?
For a long time , I've already Forgot to write an interface , Because dynamic languages don't need any direct interfaces . I thought about it carefully , If a class does have many different similar subtypes , It is natural to inherit at this time , for example ,B1,B2,B3 Inherit B. here A Yes B Dependence ,B It can be an abstract class , It can also be an interface IB, It makes no difference . conversely ,B Also can be IA rely on . This is basically what a series of design patterns are talking about .
however , Can I decouple without interface implementation ? Reasonable design of callback function can achieve . for example :
B.xxxxx(params, onXXXX, onYYYY) as long as B Define the appropriate callback function in the function parameters of the , Then I don't need B Internally call any A Methods ,A If you want to mix your own logic B Of xxxxx In the logic of the method , Just use B When , Processing these callbacks can :
b.xxxxx(params,(...)=>{
Add... Here A The logic of
},(...)=>{
Add... Here A The logic of
}); This is the time ,B If you want to be universal , Try to design appropriate parameters and callbacks .
further , You may be in A Internal use of B. such B Although the lifting of the right A Dependence , however A Yes B Our dependence is still , that , How can this coupling be further removed ? An abstract method is effective , Then use it again and again :
A.yyyyy(params, onXXXX, onYYYY); This is the time , hold A Logic and B The logic of is bound together to be the outer layer 「 responsibility 」,A and B be responsible for 「 Provision mechanism 」, Outer layer , for example C be responsible for 「 Use policy 」, So that 「 Separation of mechanism and strategy 」
C:
a ,b;
a.yyyyy(params, (...)=>{
// Other logic , Such as joining c The logic of
b.xxxxx(prams,(.....)=>{
// Join in A The logic of
}, (...)=>{
// Join in A The logic of
}
}, (...)=>{
// Other logic , Such as joining c The logic of
}); This may of course cause 「 Callback nested hell 」, in many instances , You can use the... Provided by the language layer async/await To make the code clearer . however async/await It is not a complete substitute for callback , It can only make the asynchronous callback of a single exit become 「 Pseudo synchronization 」 Code . for example :
xxx((ret)=>{
zzzz(ret)
});become :
let ret = await xxxx();
zzzz(ret);But this ability is more verbose
xxxx((ret)=>{
zzzz(ret);
},(ret)=>{
yyyy(ret);
}); To handle this multi exit callback , If xxx The interior is either in the 1 Callback ends , Or in the first 2 Callback ends , The return value can be used to determine what to do :
let {err,ret} = await xxxxx();
if(err){
zzzz(ret);
}else{
yyyy(ret);
} however , If xxxx The interior is in the 1 After a callback , It is also possible to call the... Again 2 A callback . Or any callback will call multiple times . This is the time to put xxxx The function becomes without callback async function , Logic will become more complex , It's not even possible .
All in all , This is a digression . My core point is , Through the design of function parameters and callbacks , You can get rid of it A<---->B This dependency . And let C The code where it is called 「 It can be seen at a glance A and B How to work together to complete the task 」, This is the key for me to consider where a lot of code should be written .
That's it , A function should be :
run(); // The mysterious task has been completed inside Or should it be :
if(a.init()){
a.xxxx();
a.zzzz();
}; Better? ? In my submission , At least at xxxx Where the upper level of the function is called , At that granularity provide intuitive this 「 What is the program doing 」 The intuitive logic of .
I think the decoupling of interfaces , There are many different scenarios for the same interface , But similar subclasses . And if not , that 「 Higher order function 」 The combination of is a better choice . This better is similar to 「 If not necessary , Wu Zeng entity 」 This kind of thinking , Or say 「 Omka razor 」 principle .
The above is the feeling of reconstruction , In refactoring projects , It also helps us understand what architecture is , Because in order to make the project achieve 「 Good structure 」, We have to understand a lot 「 Why? 」.
Speculation
I've been in the software industry for so long , One problem is , People often see the description of one aspect of a certain roast term , Just look at that term as worthless , It's not like that , A term is a hypothetical condition for its existence . And the reason why people roast , It's because these things have nothing that can be objectively measured , That is, unlike mathematics, which is a strict deductive system , Nor is it strictly random and double-blind like science , Most of the time, it is a lot of subjective behavior between creation and graffiti , So there are always people who do something wrong , Someone did the right thing , What people roast about is that they don't really understand the concept , And the phenomenon of doing best practices on it . Of course , In fact, we can use some indicators to measure your work to make the software run more stably , Provides better quality , Or become more unstable , It's getting worse .
For example, I changed the code this time , I don't have to say that this is 「 restructure 」、 In fact, I can just say 「 The program is not working properly now , The state machine inside doesn't work properly , I want to change this state machine to correct , Stable operation , At the same time, it is convenient to diagnose problems , There are good framework documents for others to read and find , Better not bother me again 」.
therefore , Do not look. 「 label 」 What is it? , And see if you are right , For example, if it's like the picture , To reconstruct such a stable system as the solar system ...
--end--
边栏推荐
- 安全省油环保 骆驼AGM启停电池魅力十足
- Although the TCGA database has 33 cancers
- 代码整洁之道--函数
- Sentinel
- [PCL self study: segmentation4] point cloud segmentation based on Min cut
- Matlb| optimal configuration of microgrid in distribution system based on complex network
- MATLB|改进的前推回代法求解低压配电网潮流
- Build an open source and beautiful database monitoring system -lepus
- 数据仓库入门介绍
- Oracle数据库的启停
猜你喜欢

数仓的字符截取三胞胎:substrb、substr、substring

Summary of wuenda's machine learning course (11)_ Support vector machine

Matlb| improved forward push back method for solving power flow of low voltage distribution network

零基础自学SQL课程 | SQL基本函数大全

Sell notes | brief introduction to video text pre training

【无标题】
![[digital ic/fpga] detect the position of the last matching sequence](/img/67/a1b575aa9b63892ed585d39e615c58.png)
[digital ic/fpga] detect the position of the last matching sequence
![[PCL self study: Segmentation3] PCL based point cloud segmentation: region growth segmentation](/img/9e/f08ce0729c89b0205c0ac47c523ad7.png)
[PCL self study: Segmentation3] PCL based point cloud segmentation: region growth segmentation

Eliminate gaps around El image images
![计数质数[枚举 -> 空间换时间]](/img/11/c52e1dfce8e35307c848d12ccc6454.png)
计数质数[枚举 -> 空间换时间]
随机推荐
MATLB|基于复杂网络的配电系统微电网优化配置
Systematic learning + active exploration is the most comfortable way to get started!
Chenyun pytorch learning notes_ Build RESNET with 50 lines of code
ASP. Net warehouse purchase, sales and inventory ERP management system source code ERP applet source code
Promise是什么
[读书摘要] 学校的英文阅读教学错在哪里?--经验主义和认知科学的PK
互联网业衍生出来了新的技术,新的模式,新的产业类型
Differences and functions between intranet IP and public IP
Character interception triplets of data warehouse: substrb, substr, substring
Pat class B 1013
炼金术(7): 何以解忧,唯有重构
炼金术(3): 怎样做好1个业务流程的接口对接
MySQL enterprise parameter tuning practice sharing
翻译(5): 技术债务墻:一种让技术债务可见并可协商的方法
CharSequence初探
golang使用mongo-driver操作——查(数组相关)
什么是cookie,以及v-htm的安全性隐患
吴恩达《机器学习》课程总结(14)_降维
Quickly master grep commands and regular expressions
[PCL self study: pclvisualizer] point cloud visualization tool pclvisualizer