查看原文
其他

六大设计原则详解(6)-开闭原则

2017-09-24 qzs 安卓干货铺

简介:


开闭原则(OCP)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段。对于扩展是开放的,对于修改是关闭的,这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。


软件实体包括:

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

  • 抽象和类

  • 方法

下面通过实例来详细了解一下:

现在有个书店售书的场景,首先定义一个IBook类,里面有两个属性:名称、价格。

public interface IBook{ public String getName(); public int getPrice(); }

定义小说类NovelBook-实现类

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;   } }

下面是Client类

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

下面有个需求需要更改,"如果书籍的价格在50以上,就打九折出售"  对于这样的需求变化,下面有三种方法可以解决:


1.修改接口

在IBook接口中新增一个getDisPrice(),专门用来打折处理,实现类重新实现该接口。这样的修改NoverlBook和Client都要修改,而且接口本身就要求稳定,不能随意修改,所以这个方法不可取。


2.修改实现类

修改NoverlBook类中的方法,直接在房里加入打折的逻辑,但是有个问题,别人很难知道此书是否被打折了,而且写在这里容易造成价格对不上等错误,所以此方法不可取。


3.扩展实现变化

新增一个子类DisNoverlBook类,并覆写getPrice()方法,产生新的对象,修改的代码很少,影响也小。下面是DisNoverlBook类具体代码:

public class DisNovelBook implements NovelBook{  
  public DisNovelBook (String name,int price){  
       super(name,price,author);  
        }  
          //覆写价格方法,当价格大于50,就打9析 
            public int getPrice(){
   if(this.price > 50){  
     return this.price * 0.9;    
       }else{  
          return this.price ;    
            }    
          }
       }

在Client中只要修改一下实现类对象就可以了:

public class Client{  
 public static void main(Strings[] args){  
     DisNovelBook disnovel = new DisNovelBook ("笑傲江湖",100,"金庸");
          System.out.println("书籍名字:"+disnovel .getName()+"书籍价格:"+disnovel .getPrice());  
           } }

开闭原则对扩展开放,对修改关闭,并不意味着不做任何的修改,底层模块的变更,必然有高层模块进行耦合。

二.如何使用开闭原则

  • 抽象约束

通过接口或者抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;

参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;

抽象层尽量保持稳定,一旦确定即不允许修改。

  • 元数据(metadata)控制模块行为

元数据就是用来描述环境和数据的数据,通俗地说就是配置参数,参数可以从文件中获得,也可以从数据库中获得。

Spring容器就是一个典型的元数据控制模块行为的例子,其中达到极致的就是控制反转(Inversion of Control)

  • 制定项目章程

在一个团队中,建立项目章程是非常重要的,因为章程中指定了所有人员都必须遵守的约定,对项目来说,约定优于配置。

  • 封装变化

三.为什么使用开闭原则


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

  • 开闭原则是最基础的设计原则

  • 开闭原则可以提高复用性 

  • 开闭原则可以提高维护性 


  • 面向对象开发的要求 


至此六大设计原则都写完了,主要参考了<大话设计模式><设计模式之禅>,其他五个原则链接如下:

推荐阅读

 


六大设计原则详解(1)-单一职责原则


六大设计原则详解(2)-里氏替换原则


六大设计原则详解(3)-依赖倒置原则


六大设计原则详解(4)-接口隔离原则


六大设计原则详解(5)-迪米特法则






您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存