从多种策略中删除重复代码的最有效方法

时间:2016-11-14 17:31:49

标签: java spring oop design-patterns strategy-pattern

我们的项目中有3种类型的属性: CategoryAttribute ProductAttribute ProductTypeAttribute 。这些不在我们的控制之内,因为它们来自自动生成的类,并且可能包含不同类型的属性值,例如文字数字图片。现在,每个属性都有自己的策略来检索attributeValue。为简单起见,我们假设其中所有3个都有 TextStrategy NumberStrategy ImageStrategy

示例策略:

@Component
public class CategoryImageAttributeStrategy implements CategoryAttributeStrategy {

  @Override
  public boolean isApplicable(CategoryAttribute attribute) {
      return attribute.getImage() != null;
  }

  @Override
  public Object getAttributeValue(CategoryAttribute attribute) {
      //return attribute value here 
      //may be different or may be the same 
      //for ProductImageAttributeStrategy and ProductTypeImageAttributeStrategy
  }

}

虽然获取所有图像的图像值可能不同,但获取文本值是相同的,我们最终得到3个几乎相同代码的类,我真的真的不喜欢复制代码。

我考虑为每种策略类型创建一个抽象类/默认接口,例如所有3个文本策略都将继承的 DefaultTextStrategy ,要么使用更高的默认代码,要么使用自己的实现覆盖它,但是我对这种方法并不满意,因为它需要创建更多的类这么简单的任务。

甚至可能将相同类型的策略(例如图像)组合成一个?

我真的很想听听有更多有经验的人在这件事上说的话,我想学习和改进。

提前感谢您的时间。

2 个答案:

答案 0 :(得分:0)

应该只有3种策略。 TextStrategy,NumberStrategy和ImageStrategy扩展了基本策略。混合属性和策略会让它变得混乱,因为它们实际上是独立的,并且彼此之间存在多对多的关系。

让3个属性扩展单个Attribute类:CategoryAttribute,ProductAttribute和ProductTypeAttribute。

让策略根据传递给它的Attribute类对象决定需要做什么。对于Text策略,将有单个实现。对于图像策略,您可能需要对一个类进行特殊处理。

答案 1 :(得分:0)

这就是我的所作所为:

首先,我为名为“ AttributeValueStrategy ”的所有类型的策略创建了一个界面。然后添加了 3个回调(特定类型,例如NumberValueCallback等)。现在,每个策略都实现其类型和AttributeValueStrategy接口的回调接口。然后是 DefaultStrategyMethods 类,其中包含每种类型的默认“getAtrribute”,实际策略调用defaultStrategyMethods(如下所示)或只是实现自己的代码。

@Override
public Object getAttributeValue(Object attribute) {
    return defaultStrategyMethods.getNumberValue(attribute, this);
}

创建回调是因为只有实际策略才知道它应该转换为哪个类(并且有一个方法可以执行此操作),而DefaultStrategyMethods需要使用它,这就是为什么我将“this”作为第二个参数传递(这是回调本身)。

不再重复,一切都清晰干净。