在这里插入图片描述

主页传送门:💁 传送

1.开闭原则定义

       开闭原则,英文名为Open Close Principle,又称OCP原则。

Software entities like classes, modules and functions should be open for extension but closed for modifications.

       即:一个软件实体如类,模块和函数应该对拓展开放,对修改关闭。

2.开闭原则定义解读

       开闭原则的核心思想是“开放-扩展,封闭-修改”。这意味着在系统设计时,我们应该将那些可能发生变化的部分抽象出来,然后针对这些抽象接口进行编程。当需求发生变化时,我们只需要扩展新的抽象接口,而不需要修改已有的代码。这样,我们就可以实现代码的可重用性和可维护性,减少系统中的耦合和潜在的错误。

3.开闭原则优缺点

开闭原则的优点包括:

  • 提高软件实体的可复用性:使用抽象构建的框架,可以避免重复定义或编码,提高软件实体的可复用性。
  • 提高软件实体的可拓展性:基于抽象框架进行拓展新的功能,不修改原来的代码即可完成拓展性。
  • 提高软件实体的可维护性:所有的功能特性都是基于抽象框架拓展而成,各个功能特性独立且相互不影响,后期维护目标明确且方便。

然而,开闭原则也存在一些缺点:

  • 面向对象的抽象难度大:在刚开始使用抽象构建的框架考虑不全,后期已经拓展了很多功能特性,一旦抽象的基础框架发生变动,下面的拓展部分都有可能受到影响,因此需要很强、很系统的抽象能力把基础框架抽象出来,才能减少后期带来的不必要影响。

4.开闭原则案例分析

       我们举例说明什么是开闭原则,以书店销售书籍为例,类图如下:

«interface»
IBook
+getName()
+getPrice()
+getAutor()
NovelBook
+NovelBook(String name, int price, String autor)
BookStore

代码如下:
书籍类接口(IBook):

public interface IBook {

  public String getName();
  
  public String getPrice();
  
  public String getAuthor();
  
}

小说类书籍(NovelBook):

public class NovelBook implements IBook {
   private String name;
   private int price;
   private String author;

   public NovelBook(String name,int price,String author){
     this.name = name;
     this.price = price;
     this.author = author;
   }

   public String getAutor() {
     return this.author;
   }

   public String getName() {
     return this.name;
   }  

   public int getPrice() {
     return this.price;
   } 
   
}

场景类(Client):

public class Client {

   public static void main(Strings[] args){
     IBook novel = new NovelBook("笑傲江湖",100,"金庸");
     System.out.println("书籍名字:"+novel.getName()+"书籍作者:"+novel.getAuthor()+"书籍价格:"+novel.getPrice());
   }

}

项目投产生,书籍正常销售,但是我们经常因为各种原因,要打折来销售书籍,这是一个变化,我们要如何应对这样一个需求变化呢?

我们有下面三种方法可以解决此问题:

  • 修改接口
    在IBook接口中,增加一个方法getOffPrice(),专门用于进行打折处理,所有的实现类实现此方法。但是这样的一个修改方式,实现类NovelBook要修改,同时IBook接口应该是稳定且可靠,不应该经常发生改变,否则接口作为契约的作用就失去了。因此,此方案否定。

  • 修改实现类
    修改NovelBook类的方法,直接在getPrice()方法中实现打折处理。此方法是有问题的,例如我们如果getPrice()方法中只需要读取书籍的打折前的价格呢?这不是有问题吗?当然我们也可以再增加getOffPrice()方法,这也是可以实现其需求,但是这就有二个读取价格的方法,因此,该方案也不是一个最优方案。

  • 通过扩展实现变化
    我们可以增加一个子类OffNovelBook,覆写getPrice方法。此方法修改少,对现有的代码没有影响,风险少,是个好办法。

下面是修改后的类图:

«interface»
IBook
+getName()
+getPrice()
+getAutor()
NovelBook
+NovelBook(String name, int price, String autor)
OffNovelBook
+getPrice()
BookStore

代码如下:

打折类(OffNovelBook):

public class OffNovelBook extends NovelBook{

   public OffNovelBook(String name,int price,String author){
      super(name,price,author);
   }

   //覆写价格方法,当价格大于40,就打8析,其他价格就打9析
   public int getPrice(){
     if(this.price > 40){
        return this.price * 0.8;
     }else{
        return this.price * 0.9;
     }     
   } 
   
}

现在打折销售开发完成了,我们只是增加了一个OffNovelBook类,我们修改的代码都是高层次的模块,没有修改底层模块,代码改变量少,可以有效的防止风险的扩散。

5.个人总结

       实现开闭原则的关键在于抽象化和模块化。通过抽象化,我们可以将系统中的复杂部分简化为一些简单的抽象接口,从而降低系统的耦合性和复杂性。通过模块化,我们可以将系统划分为一些独立的模块,每个模块都具有明确的功能和接口,从而提高了系统的可重用性和可维护性。
       开闭原则的应用场景非常广泛,它可以应用于各种类型的应用程序和系统设计。实现开闭原则的步骤包括定义抽象接口、实现具体类、实现适配器以及扩展新的抽象接口。
       总之,开闭原则是面向对象设计中的一项重要原则,它可以帮助我们设计出更加灵活、可维护和可重用的软件系统。通过遵循开闭原则,我们可以降低系统中的耦合性和复杂性,提高代码的可重用性和可维护性。

如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏 🙌一起讨论
你的支持就是我✍️创作的动力! 💞💞💞

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐