设计原则--开闭原则(OCP)

  开闭原则是java世界里最基础的设计原则,它指导我们如何建立一个稳定,灵活的系统。

开闭原则的定义:

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

什么是开闭原则:

  开闭原则:软件实现应该对扩展开放,对修改关闭,其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化的。那什么是软件实体呢?软件实体包括以下几个部分:

  (1)项目或软件产品中按照一定的逻辑规则划分的模块

  (3)抽象和类

  (4)方法

以书店销售书籍为例:

//书籍接口
public interface IBook{
   public String getName();
   public String getPrice();
   public String getAuthor();
}

//小说类
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;
   } 
}

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

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

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

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

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

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

public class OffNovelBook implements 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;
     }     
   } 
}

为什么使用开闭原则:

  第一:开闭原则非常有名,只要是面向对象编程,在开发时都会强调开闭原则。

  第二:开闭原则是最基础的设计原则,其它的五个设计原则都是开闭原则的具体形态,也就是说其它的五个设计原则是指导设计的工具和方法,而开闭原则才是其精神领袖。依照java语言的称谓,开闭原则是抽象类,而其它的五个原则是具体的实现类。

  第三:开闭原则可以提高复用性:在面向对象的设计中,所有的逻辑都是从原子逻辑组合而来,不是在一个类中独立实现一个业务逻辑。只有这样的代码才可以复用,粒度越小,被复用的可能性越大。那为什么要复用呢?减少代码的重复,避免相同的逻辑分散在多个角落,减少维护人员的工作量。那怎么才能提高复用率呢?缩小逻辑粒度,直到一个逻辑不可以分为止。

  第四:开闭原则可以提高维护性:一款软件量产后,维护人员的工作不仅仅对数据进行维护,还可能要对程序进行扩展,维护人员最乐意的事是扩展一个类,而不是修改一个类。让维护人员读懂原有代码,再进行修改,是一件非常痛苦的事情,不要让他在原有的代码海洋中游荡后再修改,那是对维护人员的折磨和摧残。

  第五:面向对象开发的要求:万物皆对象,我们要把所有的事物抽象成对象,然后针对对象进行操作,但是万物皆发展变化,有变化就要有策略去应对,怎么快速应对呢?这就需要在设计之初考虑到所有可能变化的因素,然后留下接口,等待“可能”转变为“现实”。

 

参考:设计模式之禅

 

posted @ 2021-01-18 15:51  小狗钱钱1  阅读(65)  评论(0)    收藏  举报