从多个策略中删除重复代码的最有效方法
Most efficient way to remove duplicated code from multiple strategies
我们的项目中有 3 种类型的属性:CategoryAttribute、ProductAttribute 和 ProductTypeAttribute .这些不在我们的控制范围内,因为它们来自自动生成的 类,并且可能包含不同类型的属性值,例如文字、数字或图片。现在,每个属性都有自己的检索属性值的策略。为简单起见,我们假设所有 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 类 几乎相同的代码,我真的真的不喜欢重复代码.
我想为每个策略类型创建一个抽象的 class/default 接口,例如DefaultTextStrategy 所有 3 种文本策略都将继承并使用提供更高的默认代码或使用自己的实现覆盖它,但是我对这种方法并不满意,因为它需要创建更多类 这么简单的任务。
也许甚至可以将相同类型(例如图像)的策略合并为一个?
我很想听听更有经验的人对这件事的看法,因为我想学习和改进。
提前感谢您的宝贵时间。
应该只有3个策略。扩展基本策略的 TextStrategy、NumberStrategy 和 ImageStrategy。混合属性和策略会使它变得混乱,因为两者实际上是独立的并且彼此之间存在多对多关系。
让 3 个属性扩展单个属性 class:CategoryAttribute、ProductAttribute 和 ProductTypeAttribute。
让策略根据传递给它的属性 class 对象来决定需要做什么。对于文本策略,将有单一的实现。对于图像策略,您可能需要对 class.
进行特殊处理
这是我所做的:
首先,我为所有类型的策略创建了一个接口,名为“AttributeValueStrategy”。然后添加 3 个回调(特定类型,例如 NumberValueCallback 等)。现在,每个策略都实现了其类型的回调接口和 AttributeValueStrategy 接口。然后是 DefaultStrategyMethods class,其中包含每种类型的默认值 "getAtrribute",实际策略调用 defaultStrategyMethods(如下所示)或仅实现自己的代码。
@Override
public Object getAttributeValue(Object attribute) {
return defaultStrategyMethods.getNumberValue(attribute, this);
}
创建回调是因为只有实际策略知道它应该转换到哪个 class(并且有一个方法可以做到这一点),而 DefaultStrategyMethods 需要使用它,所以这就是我传递 "this" 的原因作为第二个参数(回调本身)。
不再重复,一切都清晰干净。
我们的项目中有 3 种类型的属性:CategoryAttribute、ProductAttribute 和 ProductTypeAttribute .这些不在我们的控制范围内,因为它们来自自动生成的 类,并且可能包含不同类型的属性值,例如文字、数字或图片。现在,每个属性都有自己的检索属性值的策略。为简单起见,我们假设所有 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 类 几乎相同的代码,我真的真的不喜欢重复代码.
我想为每个策略类型创建一个抽象的 class/default 接口,例如DefaultTextStrategy 所有 3 种文本策略都将继承并使用提供更高的默认代码或使用自己的实现覆盖它,但是我对这种方法并不满意,因为它需要创建更多类 这么简单的任务。
也许甚至可以将相同类型(例如图像)的策略合并为一个?
我很想听听更有经验的人对这件事的看法,因为我想学习和改进。
提前感谢您的宝贵时间。
应该只有3个策略。扩展基本策略的 TextStrategy、NumberStrategy 和 ImageStrategy。混合属性和策略会使它变得混乱,因为两者实际上是独立的并且彼此之间存在多对多关系。
让 3 个属性扩展单个属性 class:CategoryAttribute、ProductAttribute 和 ProductTypeAttribute。
让策略根据传递给它的属性 class 对象来决定需要做什么。对于文本策略,将有单一的实现。对于图像策略,您可能需要对 class.
进行特殊处理这是我所做的:
首先,我为所有类型的策略创建了一个接口,名为“AttributeValueStrategy”。然后添加 3 个回调(特定类型,例如 NumberValueCallback 等)。现在,每个策略都实现了其类型的回调接口和 AttributeValueStrategy 接口。然后是 DefaultStrategyMethods class,其中包含每种类型的默认值 "getAtrribute",实际策略调用 defaultStrategyMethods(如下所示)或仅实现自己的代码。
@Override
public Object getAttributeValue(Object attribute) {
return defaultStrategyMethods.getNumberValue(attribute, this);
}
创建回调是因为只有实际策略知道它应该转换到哪个 class(并且有一个方法可以做到这一点),而 DefaultStrategyMethods 需要使用它,所以这就是我传递 "this" 的原因作为第二个参数(回调本身)。
不再重复,一切都清晰干净。