设计模式七大原则

设计模式七大原则

没有最好的设计,只有最适合的设计

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怎么卷,只要新技术出现,那么我们只需要做俩步:

  1. 实现该技术的类
public class GoCourse inplements ICourse{
    void study(){
    System.out.println("GoCourse");
}
  1. 然后传入便可以。
    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. 版本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 最后一段话,受益匪浅

posted @   帅气的涛啊  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示

目录