使用策略还是其他课程?

时间:2020-10-14 11:37:57

标签: java oop design-patterns strategy-pattern

我有以下代码示例(下面的代码)。

我有接口OnlyReverseOnlySplit,它们定义对类Data的操作。有时,我将只有可用于倒车的课程,有时,我将能够进行倒车和拆分。

在代码中,我有2种方法。

第一种方法是针对这两个单独的用例ReverseAndSplitImplOnlyReverseImpl使用2个单独的类。在这里,我不喜欢我需要附加的类,而不必在这两个类之间重复一些代码。

第二种方法是对两个用例SingleClassForReverseAndSplitImpl使用1类,然后使用策略注入NormalSplitNoSplit。在这里,我不喜欢这种额外的NoSplit类,它基本上是人为的。

根据接口隔离原则-我需要拥有ReverseAndSplit加入接口,还是应该始终单独使用两个接口(例如SingleClassForReverseAndSplitImpl implements OnlyReverse, OnlySplit而不是SingleClassForReverseAndSplitImpl implements ReverseAndSplit)?

从长远来看,哪种方法更好(将来会更灵活)?

class Data{
  String a;
}

interface OnlyReverse{
  Data getData();
  OnlyReverse reverse();
}

interface OnlySplit{
  OnlySplit split();
}

interface ReverseAndSplit extends OnlyReverse, OnlySplit{
  @Override
  ReverseAndSplit reverse();
  @Override
  ReverseAndSplit split();
}

//------------------------- USE DISTINCT CLASSES; ONE HAS SPLIT OTHER NO

class ReverseAndSplitImpl implements ReverseAndSplit{
  Data data;

  public ReverseAndSplitImpl(Data data) {
    this.data = data;
  }

  @Override
  public Data getData() {
    return data;
  }

  @Override
  public ReverseAndSplit reverse() {
    //here reverse and return
    return new ReverseAndSplitImpl(data);
  }

  @Override
  public ReverseAndSplit split() {
    //here split and return
    return new ReverseAndSplitImpl(data);
  }
}

class OnlyReverseImpl implements OnlyReverse{
  Data data;

  public OnlyReverseImpl(Data data) {
    this.data = data;
  }

  @Override
  public Data getData() {
    return data;
  }

  @Override
  public OnlyReverse reverse() {
    return new OnlyReverseImpl(data);
  }
}

//------------------------- USE DISTINCT CLASSES; ONE HAS SPLIT OTHER NO

//------------------------- USE STRATEGY TO CHOOSE TO HAVE SPLITTING OR NO
interface SplitStrategy{
  Data split(Data data);
}
class NormalSplit implements SplitStrategy{
  @Override
  public Data split(Data data) {
    return new Data();
  }
}
//NullObject pattern
class NoSplit implements SplitStrategy{
  @Override
  public Data split(Data data) {
    return data;
  }
}

class SingleClassForReverseAndSplitImpl implements ReverseAndSplit{
  Data data;
  SplitStrategy splitStrategy;

  public SingleClassForReverseAndSplitImpl(Data data, SplitStrategy splitStrategy) {
    this.data = data;
    this.splitStrategy = splitStrategy;
  }

  @Override
  public Data getData() {
    return data;
  }

  @Override
  public ReverseAndSplit reverse() {
    //here reverse and return
    return new SingleClassForReverseAndSplitImpl(data, splitStrategy);
  }

  @Override
  public ReverseAndSplit split() {
    //here split and return
    SingleClassForReverseAndSplitImpl s = new SingleClassForReverseAndSplitImpl(data, splitStrategy);
    s.data = splitStrategy.split(data);
    return s;
  }
}
//------------------------- USE STRATEGY TO CHOOSE TO HAVE SPLITTING OR NO

public class Decorator {

  public static void main(String[] args) {

    ReverseAndSplit s11 = new SingleClassForReverseAndSplitImpl(new Data(), new NoSplit());
    s11 = s11.reverse();
    s11 = s11.split();  //has split operation, but NoSplit will do nothing

    OnlyReverse s12 = new OnlyReverseImpl(new Data());
    s12 = s12.reverse();
    //has no split operation present

    //Going from NoSplit to SplitAndReverse
    ReverseAndSplit s21 = new SingleClassForReverseAndSplitImpl(s11.getData(), new NormalSplit());
    s21 = s21.reverse();
    s21 = s21.split();  //has split and now it is using NormalSplit

    ReverseAndSplit s22 = new ReverseAndSplitImpl(s12.getData());
    s22 = s22.reverse();
    s22 = s22.split();

  }
}

2 个答案:

答案 0 :(得分:0)

我认为使用第一种方法(两个简单的接口)是合理的,但不要将它们称为OnlyReverseOnlySplit,而是将它们称为ReverseSplit。因此将它们组合在一起是合理的,将来您也可以只使用其中之一。

但这也取决于您的域对象,因此很难为您做出选择。但是我不会创建名为NoSplit的接口,因为您仍然可以实现ReverseAndSplit NoSplit,这对您没有意义。

答案 1 :(得分:0)

根据接口隔离原理,如果您有从不拆分的客户端,则不应为该客户端提供包含div方法的接口。策略/空对象方法适用于有时需要拆分而有时不需要拆分的单个客户。单独的接口方法适合具有不同要求的两个不同的客户端。