感悟:很多人看设计模式时可能忽略了设计原则,包括笔者自己;

笔者自己工作经历的项目到现在,基本都违背了设计原则;为什么设计原则如此重要,就像最近几年出现的中台概念一样,设计原则本质作用就是如何设计以及设计的原则;

面向接口编程,为什么面向接口,什么样的接口是设计较ok的,为什么spring源码中很多都是接口+抽象类+实现类的这种设计style?

开闭原则

开闭原则:开放扩展,关闭修改;开闭原则s总纲,是所有设计原则的指导思想,
我们要了解其的3W原则 what-是什么,why-为什么,how-怎么做;

首先说一个案列: 开发项目时往往会随着业务修改功能,比如service某个方法做部分修改,某些程序员出于经验可能会新增一个方法来解决,从而避免对原有业务的入侵,

这样的一次迭代采用了开闭原则吗?
答:不是
开闭原则是指在已有的设计基础上做扩展,而我们在设计时,最初的设计是接口,是领域实体;并没有具体细化实现,将来的业务变更时,通过扩展原有的设计接口而非直接改动已有设计,而以上的demo仅仅是修改业务实现代码
以上才是开闭原则
由此可见,一个良好的设计师是面向接口编程!

单一职责原则:

单一职责的目的是降低对象复杂度提高可读性可维护性
比如IUser{
eat();
drink();
play();
happy();
}
这样的接口 ,一个人的吃喝玩乐都齐全了,但职责过于复杂,我们可以将其拆开成多个接口;

是不是说一个方法一个接口?不是

接口的职责多少是根据业务职责多少划分的,就像微服务的粒度,并没有一个明确的定义

单一原则的本质是要求接口和类只能有一个原因引起其的变化;

 

里式替换

里式替换实际指出了继承与多态在软件设计时的正确关系
简单来说,父类在代码中可以出现的地方,子类也就可以出现

里式替换给出了很强的约束
比如1: 子类必须实现父类的方法,price方法必须按照父类的设计思想给出书的价格,如果这里输出的是书的历史价格那么则违法了里式替换原则
IBOOK{

currentPrice();
}

IOneBook(){

currentPrice(){
return 1元;
}
}

2 同时子类可有有自己的个性,例如有输出历史价格的方法

 

 

3 依赖倒置

依赖倒置的相信大家很熟悉,在spring中每个开发者都曾使用该原则
但依赖倒置的本质是说:高层不应该依赖底层,抽象不应该依赖细节

但国内程序员往往都是做业务开发,很有可能忽略了其的本质
甚至我遇见有的项目领导认为在项目开发时可以省略掉service的接口而直接使用service的实现来提升速度
对于业务开发往往这样的开发模式在项目初期更快,提高了效率,
但缺点显而易见,springIOC的期望是依赖倒置,而这种开发却直接依赖了实现类

依赖倒置的优点显而易见,解耦内聚,对上层提供功能,内聚实现

 

4 接口隔离原则

接口隔离原则:
类似于单一职责,但二者的侧重点不同
比如说现在有个用户接口
该接口的职责是 吃喝玩乐[前面说根据单一职责这是不合理的,而这里用户的职责包含吃喝玩乐,可见职责的划分并无标准,职责的粒度取决于业务的实际场景]

而该用户接口的一个实例可能出现游乐场玩乐限界上下文和小吃街吃喝上下文
那么对于接口隔离原则
此时的设计是不合理的,接口隔离希望的是为不同的模块提供不同的接口
那么此时可以建该用户接口拆成两个 吃喝,玩乐

需要注意的是,设计原则是一种指导思想,而并非僵化模式,拆成两个接口可能违背了单一职责,确满足了接口隔离;所以实际的设计方案并不一定要满足所有的设计原则而是以提高可维护,可扩展性为目标

 

迪米勒法则

迪米勒法则本质是说:保持内聚,降低侧漏现象,
以作者的一个项目案例为demo讲解
领取红包涉及红包概率

有奖项实体 概率计算实体 领奖人实体等


应用层
创建奖项集合 概率计算实体并将奖项集合赋给计算实体
计算实体将奖项结果返回应用层
应用层调用用户传入奖项完成业务

如此 用户只需要关注自己的奖励
概率只需要关注概率部分以及产出奖励结果
很好的避免的业务中彼此之间的关联,降低了耦合

迪米勒法则到底是什么:其官方解释为只与直接的朋友通信,
什么是朋友,方法体的出入参与成员变量称之为朋友
也就是一个类方法体内部new的类应该为其朋友[学过领域驱动,这里说的是领域层而非应用层,应用层创建对象是很常见的现象]

为什么在写设计模式之前写设计原则

因为笔者工作的现在,看到过很多风格的代码,但很多最终都朝着不可控的方向方法

其往往离不开设计粗糙的原因,甚至很多工作5年更多的程序员都没有设计原则的意识;

究其原因,我想设计原则在java的相关书籍中往往并不会长篇大论,很多人看过后忘记,也并没有通过项目反思设计!

而在笔者看来,对业务型程序员来说,设计原则比设计模式更重要,因为业务初期每天都会经历开发,而良好的设计才能保障更好的扩展!