博客信息

设计模式七大原则之里氏替换原则

发布时间:『 2020-03-06 08:31』  博客类别:23种设计模式  阅读(600)

  • 概念

    子类中尽量不要重写父类的方法 在适当的情况下,可以通过聚合,组合,依赖 来解决问题

  • 使用前

    需求:完成两个数的减法运算,封装成计算器;计算器的种类有很多种( 算术型计算器 、科学型计算器、程序计算器....)

    先简单的来实现算数型计算器的减法运算功能;

    package com.javaxl.design.rules.richterReplacement.before;

    /**
    * @author 小李飞刀
    * @site www.javaxl.com
    * @company
    * @create  2020-02-16 15:15
    * 所有计算器的父类
    */
    public abstract class Cal {
      protected abstract double minus(double x, double y);
    }

    //最基础的算数型的计算器
    class BaseCountCal extends Cal{

      @Override
      protected double minus(double x, double y) {
          return x - y;
      }
    }

    public class Client {
      public static void main(String[] args) {
          Cal cal = new BaseCountCal();
    //       完成6与3的减法
          System.out.println(cal.minus(6, 3));

      }
    }

需求变更,需要做一个程序计算器,完成两个数的减法

package com.javaxl.design.rules.richterReplacement.beforePlus;

/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create  2020-02-16 15:15
* 所有计算器的父类
*/
public abstract class Cal {
  protected abstract double minus(double x, double y);
}

//最基础的算数型的计算器
class BaseCountCal extends Cal {

  @Override
  protected double minus(double x, double y) {
      return x - y;
  }
}

/**
* byte i=-128;
* System.out.println((byte)(i-1)); 127
* 完成程序计算器的减法
*/
class ProcessCal extends Cal{

  @Override
  protected double minus(double x, double y) {
      return x+y;
  }
}


public class Client {
  public static void main(String[] args) {
      Cal cal = new BaseCountCal();
//       完成6与3的减法(基本算数计算器)
      System.out.println(cal.minus(6, 3));
//         完成6与3的减法(程序计算器)
      cal = new ProcessCal();
      System.out.println(cal.minus(6, 3));
  }
}

  • 使用后

    先简单的来实现算数型计算器的减法运算功能;

    这里的代码省略,与上面需求变更前的代码保持一致...

需求变更,需要做一个程序计算器,完成两个数的减法

package com.javaxl.design.rules.richterReplacement.afterPlus;

/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create  2020-02-16 15:15
* 所有计算器的父类
*/
public abstract class Cal {
  protected abstract double minus(double x, double y);
  protected abstract double mul(double x, double y);
}

//最基础的算数型的计算器
class BaseCountCal extends Cal {

  @Override
  protected double minus(double x, double y) {
      return x - y;
  }

  protected double mul(double x, double y) {
      return x * y ;
  }
}

class ProcessCal{
//   聚合Cal抽象类,不变的引用它,变化的不引用
  private Cal cal;

  public ProcessCal(Cal cal) {
      this.cal = cal;
  }

  protected double minus(double x, double y) {
      return x + y ;
  }

  protected double mul(double x, double y) {
      return cal.mul(x,y) ;
  }
}


public class Client {
  public static void main(String[] args) {
      Cal cal = new BaseCountCal();
//       完成6与3的减法(基本算数计算器)
      System.out.println(cal.minus(6, 3));

      //         完成6与3的减法(程序计算器)
      ProcessCal processCal = new ProcessCal(cal);
      System.out.println(processCal.minus(6, 3));

//       完成6与3的乘法(基本算数计算器)
      System.out.println(cal.mul(6, 3));
      //         完成6与3的减法(程序计算器)
      System.out.println(processCal.mul(6, 3));
  }
}

从上面可以看出

不遵循里氏替换原则:Cal定义的两个数的减法,直接被子类ProcessCal给覆写了,覆写的结果导致调用方Client使用的时候未能得到自己想要结果;原因在于该程序类与类之间的耦合性高(继承关系)

遵循里氏替换原则:Cal定义的两个数的减法,ProcessCal类的多数行为(加乘除)与Cal类一致,此时应该使用聚合/组合的方式,这样的话解耦了ProcessCal与Cal之间的关系,调用方Client使用减法运算的时候会更加关注ProcessCal减法的实现过程;

这也就是里氏替换所说的,建议使用聚合/组合的方式来解决依赖关系,子类尽量不要覆写父类的方法;


over......


关键字:     设计模式  

备案号:湘ICP备19000029号

Copyright © 2018-2019 javaxl晓码阁 版权所有