Java 如何重构使用;战略;? 问题
我有一个很大的类(大约1500 LOC),它使用不同的“策略”将数据从一个对象转换到另一个对象。 我这里有一个该类的代表:Java 如何重构使用;战略;? 问题,java,design-patterns,refactoring,strategy-pattern,Java,Design Patterns,Refactoring,Strategy Pattern,我有一个很大的类(大约1500 LOC),它使用不同的“策略”将数据从一个对象转换到另一个对象。 我这里有一个该类的代表: public class FooService implements FooProcessing { FooRequestTransformer fooRequestTransformer; AnotherService anotherService; InstanceVar1 iVar1; InstanceVar2 iVar2; .
public class FooService implements FooProcessing {
FooRequestTransformer fooRequestTransformer;
AnotherService anotherService;
InstanceVar1 iVar1;
InstanceVar2 iVar2;
...
此类使用一个接口(类外部):
interface TransformerStrategy {
public FooRequest transform(FooResponse response);
}
传递到此方法中(在FooService类中):
入口点在这里,它使用getResponse()
方法并匿名创建TransformerStrategy
:
public List<Foo> getFooForSomeFlow1(Param1 param1, Param2 param2, ...){
FooResponse fooResponse = anotherService.baz(fooRequest);
TransformerStrategy myTransformerStrategy = new TransformerStrategy() {
public FooRequest transform(FooResponse fooResponse) {
fooRequestTransformer.transform(param1, param2, iVar1, iVar2)
}
}
FooResponse fooResponse = getResponse(fooResponse, myTransformerStrategy);
...//other code
}
其中一条评论说,“为了测试目的,将匿名类转换为内部类”。然而,他们只改变了其中的一个,而留下了其余的人。这就像他们开始了重构的过程,在中间停止了。
因此,我想我可以完成重构过程,将所有匿名类移到内部类,然后最终移出这些类,并将StrategyProvider
移到外部类。
问题是“将匿名转换为内部”增加了更多的样板文件(请参见上面的ABCTransformerStrategy
;我必须将所有数据传递给构造函数),我不确定通过执行此重构过程我能获得多少收益
我有两个问题:
谢谢如果您想提供一组相关对象,您可以始终使用
抽象工厂
。这不是一个简单的设计模式,但最适合您
看看这个:您的提供者类实际上是一个,这正是我要建议的 通过将逻辑从
getFooForSomeFlow1
和类似方法中移出,您创建了非常松散耦合的代码,这总是需要的
仅仅出于个人偏好,我会使用一种方法来返回实例,该方法将int
值作为鉴别器。这些int可以是provider类中的静态最终变量,如:
public static final int ABCTransformerStrategy = 1;
此外,通过将工厂类抽象化,您将不再需要在每次需要使用时实例化该类,从而使代码更加简洁
编辑
正如所建议的,使用
Enum
将值转换为它们所表示的具体类是一种更理想、语义更正确的方法。根据您提供的代码示例,它表面上很复杂。为什么不简单
public List<Foo> getFooForSomeFlow1(Param1 param1, Param2 param2, ...)
{
FooResponse fooResponse = anotherService.baz(fooRequest);
FooRequest fooRequest = fooRequestTransformer
.transform(param1, param2, iVar1, iVar2);
FooResponse fooResponse2 = anotherService.bar(fooRequest);
...//other code
}
公共列表getFooForSomeFlow1(Param1 Param1,Param2 Param2,…)
{
FooResponse-FooResponse=anotherService.baz(fooRequest);
FooRequest=fooRequestTransformer
.转换(param1、param2、iVar1、iVar2);
FooResponse fooResponse2=anotherService.bar(fooRequest);
…//其他代码
}
除非您没有向我们展示其他正在发生的事情。将每个方法转换为它自己的类(即方法作为对象),这与原始重构的过程类似。如果您需要在对象实现时集中访问所有这些方法。根据您的描述,这听起来像是在从一种类型转换为另一种类型,因此让抽象工厂接受两个
类参数,并将适当的方法作为类组合的对象实例返回给调用方。我尝试了Unreputable的方法,并在getResponse()上尝试了“Inline方法”方法,但它内联了一些重复的代码(这就是为什么我们首先将重复的代码提取到getResponse()
)。我应该澄清一下,在我的问题中,getResponse()
中的代码比我显示的要多。
至于创建工厂,我无法证明在类中引入更多样板文件和LOC是合理的,特别是因为我必须将大量数据传递到工厂方法和/或内部类中
我们所做的是用如下方法包装匿名内部类:
private TransformerStrategy createTransformerStrategyWithABCValues(Param1 param1, Param2 param2, IVar ivar, IVar1 ivar2) {
return new TransformerStrategy() {
public FooRequest transform(FooResponse response) {
return FooRequestTransformer.transform(
param1,
param2,
iVar1,
iVar2);
}
};
}
现在调用方法如下所示:
public List<Foo> getFooForSomeFlow1(Param1 param1, Param2 param2, ...){
FooResponse fooResponse = anotherService.baz(fooRequest);
TransformerStrategy myTransformerStrategy = createTransformerStrategyWithABCValues(param2, param2, iVar1, iVar2);
FooResponse fooResponse = getResponse(fooResponse, myTransformerStrategy);
...//other code
}
公共列表getFooForSomeFlow1(Param1 Param1,Param2 Param2,…){
FooResponse-FooResponse=anotherService.baz(fooRequest);
TransformerStrategy myTransformerStrategy=创建TransformerStrategyWithABCValues(参数2、参数2、iVar1、iVar2);
FooResponse FooResponse=getResponse(FooResponse,myTransformerStrategy);
…//其他代码
}
在这个过程中,我们发现这5种策略有一些重复,因此我们可以将其归纳为3种策略。我们去掉了StrategyProvider类以及提供的内部类
使用这种方法,现在调试/维护起来比较容易,我们能够从代码中删除大量重复的内容。对不起,当我意识到.np时删除了,我删除了我的评论,并进一步澄清了问题。使用int
的首选替代方法是使用Enum
来确定需要创建哪个具体实例。同意。我现在会考虑我的答案:)
private TransformerStrategy createTransformerStrategyWithABCValues(Param1 param1, Param2 param2, IVar ivar, IVar1 ivar2) {
return new TransformerStrategy() {
public FooRequest transform(FooResponse response) {
return FooRequestTransformer.transform(
param1,
param2,
iVar1,
iVar2);
}
};
}
public List<Foo> getFooForSomeFlow1(Param1 param1, Param2 param2, ...){
FooResponse fooResponse = anotherService.baz(fooRequest);
TransformerStrategy myTransformerStrategy = createTransformerStrategyWithABCValues(param2, param2, iVar1, iVar2);
FooResponse fooResponse = getResponse(fooResponse, myTransformerStrategy);
...//other code
}