设计模式七大原则
设计模式七大原则
没有最好的设计,只有最适合的设计
1. 开放封闭原则
Software entities like classes,modules and functions should be open for extension but closed for modifications.
软件实体(像类、模块、函数)应该对扩展开放、对修改关闭。
开闭原则提高维护性、提高复用性,是最基本的设计原则
看如下的例子:
interface IBook{
String getBookName();
// 注:只是为了测试,关于金钱,java中应该使用BigDecimal
double getPrice();
}
class NovelBook implements IBook{
private String bookName;
private double price;
NovelBook(String bookName,double price){
this.bookName=bookName;
this.price=price;
}
@Override
public String getBookName(){
return this.bookName;
}
@Override
public double getPrice(){
return this.price;
}
}
public static void main(String[] args){
NovelBook book=new NovelBook("设计模式",30);
System.out.println(book.getPrice());
}
现在因为某某原因,老板想要打折回笼资金,那需要怎么办呢?
根据开闭原则,对修改关闭,对扩展开放,我们开发如下类:
class OffNovelBook extends NovelBook{
OffNovelBook(String bookName,double price){
super(bookName,price);
}
@Override
public double getPrice(){
return super.getPrice() *0.8;
}
}
这样就实现了需求,又没有修改原有的类。
开闭原则不上到那么抽象的层次的话,指的是比如说从父类继承实现子类时,可以扩展一下来丰富/充实/特化其继承来的抽象功能(父类普通搬砖,子类扩展成对接受的砖进行某种特定方式搬)或者新建一个类里面包含一个搬砖类实例(因此只通过组合调用搬砖类功能来实现更复杂功能,不修改搬砖类本身的功能职责),不能在扩展类中把从父类继承的的职责功能修改了(继承来的名字叫搬砖,实现的功能是挖沙(来源知乎:包租婆粉丝团帮厨)
当然现实中不可能都遵循打折的例子,当变化来临时,你需要考虑进行重构来适应未来可能会发生的变化。
2. 单一职责原则
There should never be more than one reason for a class to change。一个类而言应该仅有一个引起其变化的原因,专人专事。财务不要去开发,开发不要去干财务。降低代码的复杂度,减少因为修改接口带来的风险。
举个例子,假设我们要开发一个用于管理员工信息的系统,包括员工的姓名、联系方式和工作经历等信息。如果遵循单一职责原则,我们应该设计一个 Employee 类,用于保存员工的基本信息,并再设计一个 WorkExperience 类,用于保存员工的工作经历。这样,Employee 类只负责保存员工的基本信息,WorkExperience 类只负责保存员工的工作经历,这样就避免了一个类承担多个职责,从而减少了类的复杂度。(来源知乎:黄朝晖)
如果某个类负责俩个职责:A、B, A需求变化,修改类,职责B可能会受到影响。那么你为什么要将多个职责放进同一类的?日常开发,UserServiceImpl、OrderServiceImpl代码不会放在一起,这也是单一职责模式的应用,理所应当的东西,变成文字,就感觉很陌生。
3. 里氏替换原则
里式替换原则,就是子类完美继承父类的设计初衷,并做了增强(增加自己特有的方法)。
static void printList(List list){
list.stream().forEach(t-> System.out.println(t));
}
public static void main(String[] args){
ArrayList<String> list=new ArrayList<>();
list.add("wang");
list.add("liu");
printList(list);
}
虽然我方法写的接受list参数,但是我放入ArrayList也可以正常工作。
4. 依赖倒置原则
参考链接软件架构设计原则之依赖倒置原则
程序要以来抽象接口,不要依赖于具体实现。
public class Tom{
public void studyJava(){
System.out.println("Java");
}
public void studyPython(){
System.out.println("Python");
}
}
public static void main(String[] args){
Tom tom=new Tom;
tom.studyJava();
tom.studyPython();
}
现在Tom是个卷逼,现在又要学AI,现在需要在Tom类添加studyAI方法,在高层追加调用。
优化实现:
public interface ICourse{
void study();
}
public class AICourse implements ICourse{
void study(){
System.out.println("AI");
}
}
public class Tom{
void study(ICourse course){
course.study();
}
}
public static void main(String[] args){
Tom tom=new Tom;
tom.study(new AICourse());
}
现在无论Tom怎么卷,只要新技术出现,那么我们只需要做俩步:
- 实现该技术的类
public class GoCourse inplements ICourse{
void study(){
System.out.println("GoCourse");
}
- 然后传入便可以。
tom.study(new GoCourse());
5. 接口隔离原则
Clients should not be forced to depend upon interfaces that they don't use
将不同功能定义在不同接⼝中实现接⼝隔离,避免了类依赖它不需要的接⼝,减少了接⼝之间依赖的冗余性和复杂性。
interface Student{
void gotoSchool();
}
class CollegeStudent{
@Override
public void gotoSchool(){
System.out.printLn("去上学");
}
}
现在发现有些学生喜欢抽烟,小王就把方法放进学生的接口里,比如这样:
interface Student{
void gotoSchool();
void smoke();
}
设计合理吗?河里吗?不合理,有些学生不抽烟,为啥要实现smoke方法呢?
6. 迪米特原则
也叫最少知道原则,每个模块对其他模块都要尽可能少地了解和依赖,降低代码耦合度
可以参考这里:https://zhuanlan.zhihu.com/p/424552431
7. 合成/聚合原则:
尽量使⽤组合(has-a)/聚合(contains-a)⽽不是继承(is-a)达到软件复⽤的⽬的,避免滥⽤继承带来的⽅法污染和⽅法爆炸,⽅法污染指⽗类的⾏为通过继承传递给⼦类,但⼦类并不具备执⾏此⾏为的能⼒;⽅法爆炸指继承树不断扩⼤,底层类拥有的⽅法过于繁杂,导致很容易选择错误
注:
- 修改接口参数、修改返回类型
//1. 版本1
void login(String name,String password);
//2. 版本2
void login(LoginParams loginParams);
class LoginParams{
String name;
String password;
...此处可以扩展
}
当然版本2的方案比较有优势,当我们需要接入第三方登录,邮箱登录等需求,我们可以扩展LoginParams的类,而不需要修改接口。
https://www.cnblogs.com/noiplee/p/3595169.html
https://zhuanlan.zhihu.com/p/392542341 最后一段话,受益匪浅
本文来自博客园,作者:帅气的涛啊,转载请注明原文链接:https://www.cnblogs.com/handsometaoa/p/17054420.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!