当前位置: 首页 > Web前端 > JavaScript

JavaScript 中的 SOLID 原则(五):“D”代表什么

时间:2023-03-27 01:26:19 JavaScript

JavaScript中SOLID原理(五):“D”代表什么?SOLID原理(第2部分):“O”代表什么JavaScript中的SOLID原理(第3部分):“L”代表什么JavaScript中的SOLID原理(第4部分):“I”代表什么A共五篇),作者是serhiirubets,感谢您一直以来的关注。依赖倒置原则D——依赖倒置原则这个原则的意思是:高层模块不应该依赖低层模块;两者都应该依赖于抽象,抽象不应该依赖于细节,细节应该依赖于抽象。例如,假设我们要处理电影数据,我们创建一个简单的Movie类:我们单独创建一个类:classMovieStorage{setItem(data){}getItemById(id){}getAll(){}}一切正常,我们的逻辑将在别处使用。constmovieStorage=newMovieStorage()constironMan=newMovieStorage('钢铁侠','关于钢铁侠的电影')constspiderMan=newMovieStorage('蜘蛛侠','关于蜘蛛侠的电影')movieStorage.setItem(ironMan)movieStorage.setItem(spiderMan)//这里可以是不同的otherlogicmovieStorage.getItemById(1);如果我们要修改数据存储到本地文件系统,没问题,再创建一个类:现在我们需要用fileStorage替换我们使用localStorage的地方。好像没什么问题。我们只是删除并替换了4行代码,但正如我们之前讨论的那样,如果您在许多文件中多次使用localStorage,可能很难找到所有的用途并正确修改它们。如果您为此编写了测试,则所有测试也需要修改。修改后的代码可以正常工作,但是随着时间的推移,本地文件系统越来越大,我们准备换成数据库存储,MongoDB或者SQL,怎么办?遵循“单一职责原则”,我们创建了一个DB存储类:需要找到所有的文件,将文件系统的逻辑修改为数据库操作,找到所有相关文件中的调用并修改方法名和签名,为此编写的测试也需要调整。使用的地方越多,越难修改,这也是代码出现bug的原因之一。希望你能理解这个问题,让我们看看如何避免它,记住依赖倒置的原则:高层模块不应该依赖低层模块;两者都应该依赖于抽象,抽象不应该依赖于细节,细节应该依赖于抽象。让我们从抽象开始:我们创建一个MoveStorage类,这将是我们的“抽象”。抽象不应该依赖于细节,我们应该如何实现呢?很简单,我们为MoveStorage类创建方法,这些方法用来代替MoveDBStorage、MovieFileStorage。classMovieStorage{save(data){}edit(data){}getById(id){}getAll(){}}这个类就像一个接口,我们所有的代码都会用到这些方法,它们的名字不会改变,这意味着我们的高级模块(我们使用“抽象”的地方)将不依赖于我们的内部逻辑。接下来,我们为每个存储方法创建特定的类,每个类使用与我们的“抽象”类相同的方法名和参数:classMovieFileStorage{save(data){}edit(data){}getById(id){}getAll(){}}classMovieDBStorage{save(data){}edit(data){}getById(id){}getAll(){}}最后我们调整我们的“抽象”:classMovieStorage{constructor(storage){this.storage=存储;}save(data){this.storage.save(data)}edit(data){this.storage.edit(data)}getById(id){this.storage.getById(id)}getAll(){this.storage.getAll()}}现在我们的“抽象”独立于细节,MovieStorage接受任何存储的实例,并且实例遵循我们的接口:constmovieStorage=newMovieStorage(newMovieFileStorage())movieStorage.save(ironMan)movieStorage.save(spiderMan)moveStorage.getById(1)如果我们要将文件存储改为缓存存储、本地/会话存储、MongoDB、SQL等,只需要准备相应的存储类(针对mongo、redis、sql),它应该实现与我们的“抽象”同名的方法,并将新类实例传递给构造函数:movieStorage.getById(1)我们只是更改传递的参数:MovieStorage从新的MovieFileStora接收实例ge()更改为newMovieDBStorage()我们不需要查找和修改所有文件,也不需要修改现有测试。我们所有的文件都使用相同的抽象,我们的抽象不依赖于逻辑,抽象就是逻辑。JS中的“SOLID”到此结束,希望您能及时使用其中的至少一个。你可以全部使用,也可以只选择一个,比如:单一职责原则,检查你的代码是否遵循这个原则,如果没有,那就重构你的代码。你也可以使用“依赖倒置原则”,检查你的代码是否符合这个原则,幸运的是,像“Angular”或“NestJS”这样的框架遵循这个原则,你可以在使用它们的项目中具体实践。让我们来回顾一下:1.单一职责原则(SRP):一个类应该有一个且只有一个职责来解决一个特定的任务。2.开闭原则(OCP):一个类应该对扩展开放,对修改关闭。如果某个类已在应用程序的其他地方使用,则不应修改该类。3.里氏替换原则(LSP):派生子类应该能够替换基类,也就是说,任何可以出现基类的地方都可以被子类替换。值得注意的是,在通过继承实现多态行为时,如果派生类不遵守LSP,可能会导致系统抛出异常。4.接口隔离原则(ISP):基类不应该包含其子类不使用的方法,也就是说一个接口应该有尽可能少的行为。那些大而全的接口应该拆分成一些小而具体的接口,让客户只需要关心他们需要使用的接口。5.依赖倒置原则(DIP):高层模块不应该依赖低层模块,而应该依赖抽象类或接口。也就是说,你不应该在高层模块中使用特定的低层模块,你应该遵循和依赖一个抽象(接口)而不是一个实例(类)。谢谢阅读!欢迎关注微信公众号“混沌前端”。