【发布时间】:2020-10-14 11:37:57
【问题描述】:
我有以下代码示例(代码如下)。
我有接口OnlyReverse 和OnlySplit,它们定义了对Data 类的操作。有时我的课程仅可用于倒车,有时我将能够进行倒车和拆分。
在代码中我有两种方法。
第一种方法是为这 2 个单独的用例 ReverseAndSplitImpl 和 OnlyReverseImpl 使用 2 个单独的类。在这里我不喜欢我需要额外的类,并且我需要在这两个类之间复制一些代码。
第二种方法是为两个用例SingleClassForReverseAndSplitImpl 使用一个类,然后使用策略注入NormalSplit 或NoSplit。这里我不喜欢这个额外的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();
}
}
【问题讨论】:
-
提供替代方案/
ReverseAndSplit不一定是坏 的事情,坏的是让您的代码依赖于那些更具体的接口。出于实现目的,通常更容易聚合和利用单个接口
标签: java oop design-patterns strategy-pattern