美文网首页
设计原则(一)开闭原则

设计原则(一)开闭原则

作者: 六脉神见 | 来源:发表于2018-09-22 22:11 被阅读0次

    1、英文定义:

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

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

    举个列子:

    image.png

    如图:有一个汽车服务中心,为路过的汽车提供补给,有一Car类,代表过往的汽车定义了一个refuel(加油)方法,服务类调用refuel为车加油。

    代码如下:

    
    /**
     * 汽车类
     * @author saisaimayi
     *
     */
    public class Car {
        
        private String name;
        
        public Car(String name){
            this.name = name;
        }
        
        public void refuel(){
            System.out.println("refuel for "+name+" car...");
        }
    }
    
    /**
    
    * 汽车服务中心
    
    * @author saisaimayi
    
    *
    
    */
    
    public class CarServiceCenter {
    
    private List<Car> cars = new ArrayList<Car>();
    
    public void addCar(Car car){
    
    cars.add(car);
    
    }
    
    public void service(){
    
    System.out.println("service for cars...");
    
    for (Car car : cars) {
    
    car.refuel();
    
    }
    
    }
    
    }
    
    public class Client extends TestCase {
    
    public void test(){
    
    CarServiceCenter center = new CarServiceCenter();
    
    center.addCar(new Car("volkswagan"));
    
    center.addCar(new Car("benz"));
    
    center.service();
    
    }
    
    }
    
    

    这个时候如果需要添加另外一种新能源的车,不需要加油,而是需要充电(charge)。

    这个时候需要怎么设计? 一般有以下两种设计方法:

    1、在类Car中新增一个charge方法,判断如果是新能源汽车,就充电,很显然,这不是一种好的设计,意味着要改变原有的代码,给原本稳定的功能带来的新的风险。

    2、修改设计,把Car抽象为接口,各种车实现该接口。

    修改后的结构如下:

    image.png

    将Car抽象为接口,其它各种车实现该接口,实现refeul方法.新能源汽车的refuel方法,调用自身的charge方法实现充电。

    代码如下:

    
    /**
    
    * 车接口
    
    * @author saisaimayi
    
    *
    
    */
    
    public interface ICar {
    
          public void refuel();
    
    }
    
    /**
    
    * 普通车
    
    * @author saisaimayi
    
    *
    
    */
    
    /**
     * 普通车
     * @author saisaimayi
     *
     */
    public class NormalCar implements ICar {
        
        private String name;
        
        public NormalCar(String name){
            this.name = name;
        }
    
        public void refuel() {
            System.out.println("refuel for normalcar "+name+"...");
        }
    }
    
    /**
     * 电动车
     * @author saisaimayi
     *
     */
    public class ElectricCar implements ICar {
        
        private String name;
        
        public ElectricCar(String name){
            this.name = name;
        }
    
        public void refuel() {
            System.out.println("need charge for electric car..");
            charge();
        }
    
        private void charge() {
            System.out.println("charge for electric car "+name+"..");
            
        }
    }
    
    /**
    
    * 测试类
    
    * @author saisaimayi
    
    *
    
    */
    
    /**
     * 测试类
     * @author saisaimayi
     *
     */
    public class Client extends TestCase {
    
        public void test(){
            CarServiceCenter center = new CarServiceCenter();
            ICar volkswagan = new NormalCar("volkswagan");
            ICar benz = new ElectricCar("benz");
            center.addCar(volkswagan);
            center.addCar(benz);
            center.service();       
        }
    }
    
    service for cars...
    refuel for normalcar volkswagan...
    need charge for electric car..
    charge for electric car benz..
    

    使用开闭原则的理由:

    1、由于对修改关闭,可以保证有新增功能时,原有代码的安全性。减少对原有功能回归测试耗费的时间和风险。

    2、缩小代码的逻辑粒度,增强可复用性。代码可复用的概率是由代码的粒度决定的,一般来说,代码的逻辑粒度越小,越容易被复用。一个功能复杂的类,复用起来可能会带来很多不便,但是如果拆分成多个小模块,可复用的概率就提高了。开闭原则让扩展和原来的接口分离,实现了逻辑的拆分。

    3、提高可靠性和可维护性。维护人员修改代码只需关注自己扩展的部分,可以尽量避免历史代码带来的束缚与不确定的风险。

    相关文章

      网友评论

          本文标题:设计原则(一)开闭原则

          本文链接:https://www.haomeiwen.com/subject/wmytoftx.html