在最开始,先重复一下第一篇的内容,这个系列是写我们如何来组织代码,如何提高可扩展性和维护性的,并不涉及到网络拓补结构或各类中间件的使用。
首先,提一提面向对象设计的五大原则:SOLID。
SOLID原则
SOLID都是些什么呢?
SRP, Single responsibility principle,单一职责。一个类只能有一个职责,如果这个类需要被修改,那只能是某一个需求更改导致的(仅此一个,没有更多的)。例如,book类里面有一个print的函数,当我们修改book类的书名时,我们需要改book类,当我们把book的打印从打印到A4改成打印成6寸时,也需要修改此类,这就违背了SRP原则。
OCP, Open/closed principle,开闭原则,Open for extension, but closed for modification
LSP, Liskov substitution principle,父类能够被子类无忧的替代,不必担心产生副作用。
ISP, Interface segregation principle,如果一个接口能够被拆分成多个接口,那就不该用这个通用的接口来呈现。
DIP, Dependency Inversion principle,依赖于抽象,而不依赖与具体的实现。
今天先从SRP和DI开始。
单一职责
它的定义上面已经讲过了。
这一条是用来帮助我们创建更为松耦合和模块化的程序,因为每种不同的行为我们都封装到一个新的类或对象里面去了。未来要增加新的行为或特性,新增的内容也会增加新的对象里面,而不是把这些行为加到原来的对象上去。
这样做的好处是更安全,更不容易出错,因为以前的类可能是含有多种多样的依赖关系的,但新增加的类却没有那些依赖在里面。所以我们可以放心的修改系统行为,不必担心修改带来的副作用。
在分层结构中,这个思想也有体现。我们的UI/Presentation层专管UI的显示,logic层专攻业务逻辑,数据访问层只做数据访问相关内容。其实,都是同样的道理。
如果SRP思想贯穿了你的整个程序,你的逻辑层里的某一个服务是不是就成了微服务,一个微服务只有一个单一的职责,你要给你的程序增加功能,那再加一个微服务即可(切忌在已有的微服务上添加)
依赖反转(Dependency Inversion)
应用程序内部的依赖不应该依赖于具体的实现,应该依赖于抽象。
也是五大原则之一。
很多应用的依赖是在编译期就确定了依赖的顺序,就如同模块A调用了模块B的一个函数,刚好这个模块B内的函数又调用了模块C的某个函数,于是,A就依赖B,B依赖于C。
应用了DIP之后,就像这个样子:
可以看到,ClassA不再依赖于Class B,转而依赖InterfaceB,ClassB也不再依赖于Class C,转变成Interface B依赖于Interface C。
ClassA现在依赖的是B的抽象(即Interface B