创建一个仅用一个函数/模块/类就可以处理这组不同事物的抽象

简介: 在软件开发中,良好的变量名和函数名能够显著提升代码的可读性和可维护性。对于变量命名,建议使用有意义且易于发音的名字(如 `currentDate` 而非 `yyyymmdstr`),对同类变量使用一致的词汇(如统一使用 `getUser`),以及使用解释性的变量名以减少理解成本(如使用常量 `MILLISECONDS_IN_A_DAY` 替代数字 `86400000`)。此外,避免不必要的上下文重复,并使用默认参数代替逻辑运算。对于函数,应限制参数数量(理想情况下不超过两个),确保每个函数只做一件事,并且函数名应清晰描述其功能。通过遵循这些原则,代码将更加简洁明了。

在开发中,变量名,函数名一般要做到清晰明了,尽量做到看名字就能让人知道你的意图,所以变量和函数命名是挺重要,今天来看看如果较优雅的方式给变量和函数命名。

一、变量

使用有意义和可发音的变量名

// 不好的写法 const yyyymmdstr = moment().format("YYYY/MM/DD"); // 好的写法 const currentDate = moment().format("YYYY/MM/DD");
对同一类型的变量使用相同的词汇

// 不好的写法 getUserInfo(); getClientData(); getCustomerRecord(); // 好的写法 getUser();
使用可搜索的名字

我们读的会比我们写的多得多,所以如果命名太过随意不仅会给后续的维护带来困难,也会伤害了读我们代码的开发者。让你的变量名可被读取,像 buddy.js 和 ESLint 这样的工具可以帮助识别未命名的常量。

// 不好的写法 // 86400000 的用途是什么? setTimeout(blastOff, 86400000); // 好的写法 const MILLISECONDS_IN_A_DAY = 86_400_000; setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
使用解释性变量

// 不好的写法 const address = "One Infinite Loop, Cupertino 95014"; const cityZipCodeRegex = /^[^,]+[,\s]+(.+?)\s(\d{5})?$/; saveCityZipCode( address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2] ); // 好的写法 const address = "One Infinite Loop, Cupertino 95014"; const cityZipCodeRegex = /^[^,]+[,\s]+(.+?)\s(\d{5})?$/; const [_, city, zipCode] = address.match(cityZipCodeRegex) || []; saveCityZipCode(city, zipCode);
避免费脑的猜测

显式用于隐式

// 不好的写法 const locations = ["Austin", "New York", "San Francisco"]; locations.forEach(l => { doStuff(); doSomeOtherStuff(); // ... // ... // ... // 等等,“l”又是什么? dispatch(l); // 好的写法 const locations = ["Austin", "New York", "San Francisco"]; locations.forEach(location => { doStuff(); doSomeOtherStuff(); // ... // ... // ... dispatch(location); });
无需添加不必要的上下文

如果类名/对象名已经说明了,就无需在变量名中重复。

// 不好的写法 const Car = { carMake: "Honda", carModel: "Accord", carColor: "Blue" }; function paintCar(car) { car.carColor = "Red"; } // 好的写法 const Car = { make: "Honda", model: "Accord", color: "Blue" }; function paintCar(car) { car.color = "Red"; }
使用默认参数代替逻辑或(与)运算

// 不好的写法 function createMicrobrewery(name) { const breweryName = name || "Hipster Brew Co."; // ... } // 好的写法 function createMicrobrewery(name = "Hipster Brew Co.") { // ... }
二、函数

函数参数(理想情况下为2个或更少)

限制函数参数的数量是非常重要的,因为它使测试函数变得更容易。如果有三个以上的参数,就会导致组合爆炸,必须用每个单独的参数测试大量不同的情况。

一个或两个参数是理想的情况,如果可能,应避免三个参数。除此之外,还应该合并。大多数情况下,大于三个参数可以用对象来代替。
https://nanjing.92demo.com/sitemap
// 不好的写法 function createMenu(title, body, buttonText, cancellable) { // ... } createMenu("Foo", "Bar", "Baz", true); // 好的写法 function createMenu({ title, body, buttonText, cancellable }) { // ... } createMenu({ title: "Foo", body: "Bar", buttonText: "Baz", cancellable: true });
函数应该只做一件事

这是目前为止软件工程中最重要的规则。当函数做不止一件事时,它们就更难组合、测试和推理。可以将一个函数隔离为一个操作时,就可以很容易地重构它,代码也会读起来更清晰。

// 不好的写法 function emailClients(clients) { clients.forEach(client => { const clientRecord = database.lookup(client); if (clientRecord.isActive()) { email(client); } }); } // 好的写法 function emailActiveClients(clients) { clients.filter(isActiveClient).forEach(email); } function isActiveClient(client) { const clientRecord = database.lookup(client); return clientRecord.isActive(); }
函数名称应说明其作用

// 不好的写法 function addToDate(date, month) { // ... } const date = new Date(); // 从函数名称很难知道添加什么 addToDate(date, 1); // 好的写法 function addMonthToDate(month, date) { // ... } const date = new Date(); addMonthToDate(1, date);
函数应该只有一个抽象层次

当有一个以上的抽象层次函数,意味该函数做得太多了,需要将函数拆分可以实现可重用性和更简单的测试。

// 不好的写法 function parseBetterJSAlternative(code) { const REGEXES = [ // ... ]; const statements = code.split(" "); const tokens = []; REGEXES.forEach(REGEX => { statements.forEach(statement => { // ... }); }); const ast = []; tokens.forEach(token => { // lex... }); ast.forEach(node => { // parse... }); } // 好的写法 function parseBetterJSAlternative(code) { const tokens = tokenize(code); https://92demo.com/sitemap/post49.html:const syntaxTree = parse(tokens); syntaxTree.forEach(node => { // parse... }); } function tokenize(code) { const REGEXES = [ // ... ]; const statements = code.split(" "); const tokens = []; REGEXES.forEach(REGEX => { statements.forEach(statement => { tokens.push(/ ... /); }); }); return tokens; } function parse(tokens) { const syntaxTree = []; tokens.forEach(token => { syntaxTree.push(/ ... /); }); return syntaxTree; }https://92demo.com/sitemap/post64.html
删除重复的代码

尽量避免重复的代码,重复的代码是不好的,它意味着如果我们需要更改某些逻辑,要改很多地方。

通常,有重复的代码,是因为有两个或多个稍有不同的事物,它们有很多共同点,但是它们之间的差异迫使我们编写两个或多个独立的函数来完成许多相同的事情。 删除重复的代码意味着创建一个仅用一个函数/模块/类就可以处理这组不同事物的抽象。

获得正确的抽象是至关重要的,这就是为什么我们应该遵循类部分中列出的 「SOLID原则」。糟糕的抽象可能比重复的代码更糟糕,所以要小心!说了这么多,如果你能做一个好的抽象,那就去做吧!不要重复你自己,否则你会发现自己在任何时候想要改变一件事的时候都要更新多个地方。

「设计模式的六大原则有」

Single Responsibility Principle:单一职责原则
Open Closed Principle:https://92demo.com/sitemap/post1.html,开闭原则
Liskov Substitution Principle:里氏替换原则
Law of Demeter:迪米特法则
Interface Segregation Principle:接口隔离原则
Dependence Inversion Principle:依赖倒置原则
把这六个原则的首字母联合起来(两个 L 算做一个)就是 SOLID (solid,稳定的),其代表的含义就是这六个原则结合使用的好处:建立稳定、灵活、健壮的设计。下面我们来分别看一下这六大设计原则。

「不好的写法」

相关文章
31 # 模块的概念
31 # 模块的概念
60 0
|
4月前
|
设计模式
建模底层逻辑问题之以命令设计模式为例,要用定义法建模,如何实现
建模底层逻辑问题之以命令设计模式为例,要用定义法建模,如何实现
|
1月前
ES6的类的实例化过程和传统面向对象语言有什么区别?
ES6 的类的实例化过程更加简洁、直观,并且与现代编程理念更加契合,减少了一些传统面向对象语言中可能存在的复杂性和冗余性。
|
7月前
|
存储 编译器 C语言
C++:类的概念
C++:类的概念
50 0
|
7月前
|
uml
通过简单例子 | 快速理清 UML 中类与类的六大关系
通过简单例子 | 快速理清 UML 中类与类的六大关系
134 0
|
算法 C++ 容器
关系类算法函数
关系类算法函数
|
编解码
失真的概念和定义
失真的概念和定义
258 0
|
前端开发
前端学习案例9-寄生组合继承2
前端学习案例9-寄生组合继承2
61 0
前端学习案例9-寄生组合继承2
|
前端开发
前端学习案例8-寄生组合继承1
前端学习案例8-寄生组合继承1
70 0
前端学习案例8-寄生组合继承1
|
前端开发
前端学习案例7-寄生组合继承1
前端学习案例7-寄生组合继承1
76 0
前端学习案例7-寄生组合继承1