如何重构这个模板方法实现
How to refactor this template method implemetation
我有一个混蛋模板方法实现。它不是带有 subclass 实现的基础 class,而是 util class 上的一个静态方法,它采用它委托的接口。我想将其重构为更常见的模式,这样我就可以停止传递域 class。
我认为第一步是将模板转换为对象方法,但随后我对如何将我的 5 个 Helper 实现(未显示)移动到新模板对象。
public interface Helper
{
void doFirstThing(Domain d);
void doSecondThing(String id);
}
public class UtilClass
{
public static void template(Domain d, Helper h, String who)
{
//begin database transaction
try
{
//some logic
h.doFirstThing(d);
//more computation
h.doSecondThing(d.getId());
//database commit();
}
finally
{
//if transaction open database rollback();
}
}
}
public class Domain
{
public String getId()
{
return "value";
}
}
类似下面的内容...
public abstract class TemplateX
{
protected Domain _domain;
protected TemplateX(Domain domain)
{
_domain = domain;
}
protected abstract void DoFirstThing();
protected abstract void DoSecondThing();
public void DoIt(string who)
{
//begin database transaction
try
{
//some logic
DoFirstThing();
//more computation
DoSecondThing();
//database commit();
}
finally
{
//if transaction open database rollback();
}
}
}
public class Implementation1 : TemplateX
{
public Implementation1(Domain domain) : base(domain)
{
}
protected override void DoFirstThing()
{
//code from helper class here
}
protected override void DoSecondThing()
{
//code from helper class here
}
}
我又想了想,想出了以下步骤。
- 用方法对象替换方法。将帮助器排除在构造函数参数之外。我也跳过了关于制作局部变量字段的部分。当我想要完成时,自动重构做得很好。
- 内联静态方法。
- 使实现成为新 MethodObject 的子class。
这涉及 adding/modifying a/the 构造函数。
在创建方法对象并使用实现调用的地方,只需创建实现并调用模板方法即可。
new MethodObject(d, who).template(new Implementation(d, who));
变成
Implementation impl = new Implementation(d, who);
impl.template(impl);
- 对其他实现重复步骤 3 和 4。
- 使 MethodObject/Baseclass 抽象并将接口中的方法添加为抽象方法。
- 更新 MethodObject/Baseclass 以使用抽象方法。
- 删除 Helper 接口作为参数,因为它不再被使用。
- 从子class中删除接口声明。
- 删除助手界面。
- 可以删除先前在接口上定义的方法的参数,这些参数是父 class 上的字段。
这可以扩展到从字段中获取的值。由于 d 是一个字段,因此不需要传递 d.getId() 。
doSecondThing(d.getId());
我有一个混蛋模板方法实现。它不是带有 subclass 实现的基础 class,而是 util class 上的一个静态方法,它采用它委托的接口。我想将其重构为更常见的模式,这样我就可以停止传递域 class。
我认为第一步是将模板转换为对象方法,但随后我对如何将我的 5 个 Helper 实现(未显示)移动到新模板对象。
public interface Helper
{
void doFirstThing(Domain d);
void doSecondThing(String id);
}
public class UtilClass
{
public static void template(Domain d, Helper h, String who)
{
//begin database transaction
try
{
//some logic
h.doFirstThing(d);
//more computation
h.doSecondThing(d.getId());
//database commit();
}
finally
{
//if transaction open database rollback();
}
}
}
public class Domain
{
public String getId()
{
return "value";
}
}
类似下面的内容...
public abstract class TemplateX
{
protected Domain _domain;
protected TemplateX(Domain domain)
{
_domain = domain;
}
protected abstract void DoFirstThing();
protected abstract void DoSecondThing();
public void DoIt(string who)
{
//begin database transaction
try
{
//some logic
DoFirstThing();
//more computation
DoSecondThing();
//database commit();
}
finally
{
//if transaction open database rollback();
}
}
}
public class Implementation1 : TemplateX
{
public Implementation1(Domain domain) : base(domain)
{
}
protected override void DoFirstThing()
{
//code from helper class here
}
protected override void DoSecondThing()
{
//code from helper class here
}
}
我又想了想,想出了以下步骤。
- 用方法对象替换方法。将帮助器排除在构造函数参数之外。我也跳过了关于制作局部变量字段的部分。当我想要完成时,自动重构做得很好。
- 内联静态方法。
- 使实现成为新 MethodObject 的子class。 这涉及 adding/modifying a/the 构造函数。
在创建方法对象并使用实现调用的地方,只需创建实现并调用模板方法即可。
new MethodObject(d, who).template(new Implementation(d, who));
变成
Implementation impl = new Implementation(d, who);
impl.template(impl);
- 对其他实现重复步骤 3 和 4。
- 使 MethodObject/Baseclass 抽象并将接口中的方法添加为抽象方法。
- 更新 MethodObject/Baseclass 以使用抽象方法。
- 删除 Helper 接口作为参数,因为它不再被使用。
- 从子class中删除接口声明。
- 删除助手界面。
- 可以删除先前在接口上定义的方法的参数,这些参数是父 class 上的字段。 这可以扩展到从字段中获取的值。由于 d 是一个字段,因此不需要传递 d.getId() 。 doSecondThing(d.getId());