如何在不违反Liskov替换原则的情况下有效地在类之间共享函数

时间:2016-09-22 13:17:03

标签: java oop solid-principles liskov-substitution-principle

我的代码库最初是使用许多不同的选项创建的,这些选项允许您以稍微不同的方式获取执行相同过程的代码,如下所示:

public class MainFunction {
  public void main(String option){
     if (option.equals("vanilla mode")){
        this.firstFunction();
     }else{
        this.differentVersionOfFirstFunction();
     }
     this.secondFunction();
  }

  public void firstFunction(){
    //First functions code
  }

  public void secondFunction(){
     //Second functions code
  }

  public void differentVersionOfFirstFunction(){
     // different code from First functions code that produces the same type of end result using a slightly different method
  }
}

随着各种不同的选项被添加,代码变得越来越复杂,这种情况逐渐变得越来越复杂。

为了解决这个问题,我原本计划创建一个Parent对象,然后在需要时可以让子对象的Parents方法有微妙的不同变化。问题是,我明白这会违反利斯科夫替代原则,事实上我可能有孩子应该分享他们父母可能不存在的相同方法。

所以我在同一个类对象中使用不同的方法,以稍微不同的方式完成相同的工作。

public class MainFunction {
  public void main1(){
    this.firstFunction();
    this.secondFunction();
  }

  public void main2(){
    this.differentVersionOfFirstFunction();
    this.secondFunction();
  }

  public void firstFunction(){
    //First functions code
  }

  public void secondFunction(){
    //Second functions code
  }

  public void differentVersionOfFirstFunction(){
    // different code from First functions code that produces the same type of end result using a slightly different method
  }
}

我想我可以创建一个单独的Utility类来保存我的各种功能,但我不确定是否有更优雅的解决方案?

2 个答案:

答案 0 :(得分:1)

也许您可以尝试使用策略模式,在MainFunction中注入每次需要使用的Strategy对象。看看here

答案 1 :(得分:1)

我不知道你的例子是如何违反 Liskov替代原则的。但是,我看到它们可能违反了开放/封闭原则,这意味着每次需要修改程序时,都会编辑一些MainFunction.java文件,并有可能影响所有可能的运行程序的方案。更好的解决方案是使用大量的解耦组件,以便在需要修改某些内容时,只修改一小部分,这不太可能影响程序可能遇到的所有场景。这就是单一责任原则的意思。

正如另一个答案中所提到的,您的方案似乎非常适合应用策略模式。这可能如下所示:

  1. 使用MainFunction方法创建界面void main(),无需任何选项。
  2. 使用AbstractMainFunction成员创建一个抽象策略类,例如public abstract void main(),不带任何选项。该类将实现MainFunction接口。
  3. 根据需要创建AbstractMainFunction的单独实现,例如VanillaModeMainFunctionDifferentMainFunction。您可能会发现在AbstractMainFunction
  4. 中保留一些共享代码很有用
  5. 创建策略切换器类,例如MainFunctionService。它将有一个方法public void main(String option),就像你的第一个例子一样,并且可能会有一个这样的开关语句:

    MainFunction strategy = defaultFunction;
    switch(option) {
        case "vanilla":
             strategy = vanillaFunction;
             break;
        case "different":
             strategy = differentFunction;
             break;
    }
    strategy.main();
    
  6. 看起来很多事情要做,但最后你会看到这真的简化了维护和进一步开发。