@Alpacadh
2022-09-18T17:23:11.000000Z
字数 3266
阅读 259
设计模式
主要思想:一个类或者模块只负责完成一个职责(或者功能)
主要思想:软件实体(模块、类、方法等)应该“对扩展开放、对修改关闭”,即在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。
主要思想:子类对象可以替换程序中父类对象。
主要思想:客户端不应该被强迫依赖它不需要的接口。其中的“客户端”,可以理解为接口的调用者或者使用者。
理解“接口隔离原则”的重点是理解其中的“接口”二字。这里有三种不同的理解。
主要思想:这条原则跟控制反转有点类似,主要用来指导框架层面的设计。高层模块不依赖低层模块,它们共同依赖同一个抽象。抽象不要依赖具体实现细节,具体实现细节依赖抽象。
点击展开内容
主要思想:代码尽量简单。
主要思想:不要写重复的代码。重复主要指实现逻辑重复、功能语义重复和代码执行重复。
主要思想:不该有直接依赖关系的类之间,不要有依赖;有依赖关系的类之间,尽量只依赖必要的接口。
同一个Repository可能会被多个Service来调用,同一个Service可能会被多个Controller调用。比如,UserService中的getUserById()接口封装了通过ID获取用户信息的逻辑,这部分逻辑可能会被UserController和AdminController等多个Controller使用。如果没有Service层,每个Controller都要重复实现这部分逻辑,显然会违反DRY原则。
分层体现了一种抽象和封装的设计思想。比如,Repository层封装了对数据库访问的操作,提供了抽象的数据访问接口。基于接口而非实现编程的设计思想,Service层使用Repository层提供的接口,并不关心其底层依赖的是哪种具体的数据库。当我们需要替换数据库的时候,比如从MySQL到Oracle,从Oracle到Redis,只需要改动Repository层的代码,Service层的代码完全不需要修改。
除此之外,Controller、Service、Repository三层代码的稳定程度不同、引起变化的原因不同,所以分成三层来组织代码,能有效地隔离变化。比如,Repository层基于数据库表,而数据库表改动的可能性很小,所以Repository层的代码最稳定,而Controller层提供适配给外部使用的接口,代码经常会变动。分层之后,Controller层中代码的频繁改动并不会影响到稳定的Repository层。
Repository层只关注数据的读写。Service层只关注业务逻辑,不关注数据的来源。Controller层只关注与外界打交道,数据校验、封装、格式转换,并不关心业务逻辑。三层之间的关注点不同,分层之后,职责分明,更加符合单一职责原则,代码的内聚性更好。
后面讲单元测试的时候,我们会讲到,单元测试不依赖不可控的外部组件,比如数据库。分层之后,Repsitory层的代码通过依赖注入的方式供Service层使用,当要测试包含核心业务逻辑的Service层代码的时候,我们可以用mock的数据源替代真实的数据库,注入到Service层代码中。代码的可测试性和单元测试我们后面会讲到,这里你稍微了解即可。
所有的代码都放到一个类中,那这个类的代码就会因为需求的迭代而无限膨胀。我们知道,当一个类或一个函数的代码过多之后,可读性、可维护性就会变差。那我们就要想办法拆分。拆分有垂直和水平两个方向。水平方向基于业务来做拆分,就是模块化;垂直方向基于流程来做拆分,就是这里说的分层。