单一职责原则
修改一个类的理由不应该超过一个,最小化对一个类需要修改的次数是非常必要。
一个类的功能不应该太复杂,如果过于复杂应该拆分成多个类
// ❌class UserSettings {constructor(user) {this.user = user;}changeSettings(settings) {if (this.verifyCredentials) {// ...}}verifyCredentials(user) {// ...}}// ✔️ 拆分为多个类,做到更大意义上的解耦class UserAuth {constructor(user) {this.user = user;}verifyCredentials() {// ...}}class UserSettings {constructor(user) {this.user = user;this.auth = new UserAuth(user);}changeSettings(settings) {if (this.auth.verifyCredentials) {// ...}}}
开/闭原则
- 开
- 允许用户方便地扩展代码模块功能
- 闭
接口隔离原则
客户端不应该依赖不需要的接口,一个类对别一个类的依赖应该在建立在最小的接口上。
在JS中,当一个类需要许多参数才能生成一个对象时,或大多数时候不需要设置这么多参数,此时减少对配置参数数量的需要是有意义的
// ❌/*定义一个DOM遍历类构造函数中传入一个settings对象,并调用setup来初始化rootNode和animationModule所以实例化这个类时就需要转入rootNode和animationModule*/class DOMTraverser {constructor(settings) {this.settings = settings;this.setup();}setup(settings) {this.rootNode = this.settings.rootNode;this.animationModule.setup();}traverse() {// ...}}let $ = new DOMTraverser({rootNode: document.getElementsByTagName('body'),animationModule: function() {// ...}});// ✔️ 但经发现animationModule这个模块不是每次遍历都都需要,所以改为给一个options选项,/*但经发现animationModule这个模块不是每次遍历都都需要。所以改为给一个options选项,将不需要用到的属性放到options里通过判断是否传入这个属性来进行相应的初始化*/class DOMTraverser {constructor(settings) {this.settings = settings;this.options = settings.options;this.setup();}setup(settings) {this.rootNode = this.settings.rootNode;this.setupOptions();}setupOptions() {if (this.options.animationModule) {// ...}}traverse() {// ...}}let $ = new DOMTraverser({rootNode: document.getElementsByTagName('body'),options: {animationModule: function() {}}});
继承使用Class而不是Function
ES5的方式在继承构造和方法定义方面可读性较差,在需要继承时优先选用ES6 class。
虽然本质是一样的,但对于读写的人来说这种方式最为简单。
语雀内容
