1, 开闭原则(Open Closed Principle)

concept

Software entities (classes, modules, functions) should be open for extension but closed for modification
软件实体(包括类、模块、功能等)应该对扩展开放,但是对修改关闭()


analyse

  1. 相对于其他的几种设计原则来讲,开闭原则的思想就像一个纲领【用抽象构建框架,用实现扩展细节】,其他几大原则更像在这个纲领的之上进行拓展
  2. 在设计一个模块的时候,应对使这个模块可以在【不被修改】的前提下被扩展,换言之,应对可以【不必修改源代码】的情况下【改变这个模块的行为】
  3. 实现开闭原则的关键就在于“抽象”
  4. 利用接口或抽象类抽象出系统的抽象层,抽象层不变,利用实现层进行扩展;
  5. 对可变性的封装,将可变的元素封装起来,防止改变扩散到整个应用;
  6. 继承是用来封装可变性的,一般的继承层次不要超过两层;
  7. 注意控制封装的粒度,不要将两种可变性封装到一起;

example

以书店销售书籍为例

// 书籍类的接口
public interface IBook{
  public String getName();
  public String getPrice();
}
//小说类的书籍
public class NovelBook implements IBook{
   private String name;
   private int price;

   public NovelBook(String name,int price){
     this.name = name;
     this.price = price;
   }
   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("java设计模式",100);
     System.out.println("书籍名字:"+novel.getName()+"书籍价格:"+novel.getPrice());
   }
}

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

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

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

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

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

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

软件系统中包含的各种组件,例如模块(Modules)、类(Classes)以及功能(Functions)等等,应该在不修改现有代码的基础上,引入新功能。开闭原则中“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的;开闭原则中“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代码。


用抽象构建架构,用实现扩展细节。开闭原则就是一个总纲,他告诉我们要对扩展开放,对修改关闭。

  • 单一职责原则(原则详解)是从类的功能的角度去设计,将不同的职责分别归于不同的类中,这样使得设计更加清晰、易修改。

  • 接口隔离原则(原则详解)是从接口的方法设计角度去思考,强调不能过度设计接口,尽量使得接口内的方法能充分的提供给其实现类需要的功能,不要过度设计导致方法的冗余,也不要设计不充分导致,实现类中有未能抽取的公共部分。

  • 依赖倒置原则(原则详解)是从类之间依赖关系的角度去设计,强调高层不依赖于低层,低层依赖于高层,减少实现细节的依赖。

  • 迪米特法则(原则详解),从类与类之间耦合的角度去思考,降低耦合,减少不必要的耦合,不要跨越多层去调用方法,最佳的方式是只调用其朋友类的方法,之后行为由朋友类负责实施。

  • 里氏替换原则(原则详解)是从类的继承的角度去设计,强调父类被子类继承后,在父类出现的地方,可以替换为其子类,而且行为不会发生变化。

  • 组合优于继承原则(原则详解)告诉我们在系统中应尽量多使用对象间的关联关系,尽量少使用甚至不使用继承关系来达到复用已有对象的目的

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值