搜索
写经验 领红包
 > 地理

下架构件包含哪些(架构如何设计)

在生活中,很多人可能想了解和弄清楚回顾下架构设计的五大原则-SOLID的相关问题?那么关于下架构件包含哪些的答案我来给大家详细解答下。

下架构件包含哪些(架构如何设计)

设计原则

想必大家在学习面向对象的时候,都学习过下面几大原则:

SRP (Single Responsibility Principle)单一职责:该设计原则是基于康威定律的推论,每个软件模块有且只有一个被更改的理由。OCP (Open Close Principle)开闭原则:对扩展开放,对修改关闭。LSP ( Liskov Substitution Principle)里氏替换原则:任何基类可以出现的地方,子类一定可以出现。ISP (ISP InterfaceSegregation Principles)接口隔离原则:在设计中需要避免不需要的依赖。DIP (DIP Dependence Inversion Principle)依赖反转原则:高层策略性代码不应该依赖底层细节的代码,而应该是底层细节代码依赖高层策略。

这五个原则也被称为,SOLID原则取的是他们的首字母。这个也是我们做一个好设计的基础,接下来会依次对其进行解释。

SRP:单一职责

SRP很容易被大家从字面意思无界,并不是每个模块只做一个事,而是每个模块的变化原因只有一个。

任何一个软件模块都应该只对某一类行为者(有共同需求的人)负责。

SRP原则应该是大家运用得最多的原则之一。比如:有一个Employee类其中有三个函数:

calculatePay():计算工资,由财务部门制定,需要向CFO汇报。reportHours():计算工时,人力资源制定,向COO汇报save():由DBA制定,向CTO汇报。

这里三个函数都放在了Employee类中,其实也就是把三个行为者的行为都耦合在了一起。一般来说计算工资,会获取正常工时,而计算工时也会获取工时,这两个函数都依赖了一个获取工时的方法,如果财务部门计算工资时,想修改逻辑,看大家辛苦了1个小时当1.1个小时发工资,这个时候修改了这个获取工时的方法,但是HR部门并不需要这个修改,这个时候就会导致reportHours()这个方法出现数据错误。所以这个时候就需要将不同行为者的代码就行拆分。

如何解决

设计出三个类,每个类都只与一个行为者相关。这种问题的坏处是,程序员需要在程序里处理三个类,并且使用门面模式的方法,让我们只需要在我们使用的地方使用一个类即可:

这样的话我们就不需要关心其他三个类,直接调用门面模式的方法即可。

SRP的好处:

修改代码容易,由于不需要考虑修改代码是否会影响其他业务所以是很容易的。更加容易维护,维护一个什么逻辑都有的代码明显比维护一个单一职责的代码难得多。容易发现问题,当出现问题的时候,由于职责清晰,可以比较容易的定位。松耦合,职责分离,耦合程度比较低。

OCP:开闭原则

开闭原则,即应该将那些容易变化的部分进行抽象,利用对抽象的多个实现来进行对扩展开放,而不是直接在类中去修改。

我们并不需要强调将变化的部分抽象出来,修改是不可避免的,所以我们需要把控好修改的影响,所以高层组件的修改不会影响底层组件,组件层次越低越稳定。对于J2EE的开发者来说,三层开发肯定并不陌生,controller,service,dao:如果我们修改controller那么service其实是无感知的,不会受影响,如果我们修改service,dao是不会受影响的,但是我们的controller是会受影响。所以越底层的组件那么其实应该越稳定。通过这种方式我们可以控制修改范围的影响。总结起来就是通过将系统划分为一系列组件,并且将这些组件间的依赖关系按层次结构进行组织,使得高阶组件不会因低阶组件被修改而受到影响。

LSP:里氏替换

任何基类可以出现的地方,子类一定可以出现。大多数人认为LSP其实就是指导如何使用继承关系的一种方法,尤其是我们在开发的过程中用spring依赖注入的基本都是基类而非具体的实现类,这个的确也是LSP的一种实现手段。LSP也在逐渐演变成一种更广泛的,指导接口与其实现方式的设计原则。

ISP:接口隔离原则

首先大家看看下面这个例子:

我们这里的User1,User2,User3都是依赖OPS的,但是User1只需要用op1,User2用op2,User3用op3。在这种情况下,虽然User1不会和op2,op3产生直接的调用关系,但在源代码层次上也与他们形成依赖关系。这种依赖关系会导致两个问题:

修改op2,op3的逻辑会导致op1的逻辑变化就算逻辑不变化,修改op2也会导致重新编译和部署User1。

我们通过下面这种方将不同的操作隔离成接口,我们将OPS类实现这三个接口,然后替换在User1中的U1Ops,由于依赖的是最小接口所以就不会出现上面的问题。总结起来就是:不要依赖不需要的东西

DIP: 依赖反转

依赖反转其实总结起来就是多依赖抽象,少依赖具体实现。但是事事并没有那么绝对,我们的String类是一个具体的实现类但是在我们的代码中随处可见,那是不是我们就违反了DIP了呢?其实不是的,我们String已经非常稳定了,就算修改也会被严格的控制,所以我们不需要担心修改String类会发生一些意想不到的问题。所以对于我们稳定的东西,其实DIP原则就不适用了,而我们需要重点关注的应该经常变动的。这里我想要说的一点的是,大家在编码过程中写List的时候虽然大多数时候用的是ArrayList,但是其实很少写下面这句话

ArrayList list = new ArrayList(),更多的是写List list = new ArrayList(),其实这个就是DIP的一个实现。

DIP还有几个编码规则需要注意:

多使用抽象接口,尽量避免使用具体实现类。尽量不要在具体实现类上面创建子类。尽量不要覆盖继承的抽象类的方法:由于我们依赖的是抽象,有可能逻辑中已经对这些方法产生了依赖,如果覆盖有可能会造成问题。

温馨提示:通过以上关于回顾下架构设计的五大原则-SOLID内容介绍后,相信大家有新的了解,更希望可以对你有所帮助。