在我的java应用程序中,我得到了一个方法,该方法运行一长串步骤(同步),其中一个步骤的结果是下一个步骤的输入。
例如:
// Step 1
Map<String, SomeObject> objectsMap = someService.createObjectsMap();
if (!objectsMap.isEmpty()) {
// Step 2
AnotherObject anotherObject = anotherService.createAnotherObject(objectsMap);
if (null != anotherObject) {
// Step 3 that gets anotherObject as input and returns something else
} else { // Step 2 failed
// log and handle
}
} else { // Step 1 failed
// log and handle
}因此,我在一系列if-否则块中编写了这一系列步骤。由于每个步骤都有不同的签名,因此没有公共接口。我一直在研究一些不同的模式,并尝试自定义模式,如责任链和命令,但没有得到满意的结果。
我想知道这个丑陋的、冗长的、如果-否则的部分是否是要走的路,还是有一种模式可以帮助使这一系列步骤更加干净和可伸缩。
发布于 2014-10-08 07:21:11
您必须自己回答的一个问题是,为什么我要重构我的代码?
你想让它成为
重构以使代码清除
如果不需要在运行时配置这些步骤,并且希望使代码比您应该看到的注释更干净。每个评论都是一个提示。
将代码块分解为方法,并按步骤命名它们
/**
* Explain what step1 does.
*/
private void step1() {
// Step 1
Map<String, SomeObject> objectsMap = someService.createObjectsMap();
if (!objectsMap.isEmpty()) {
step2(objectsMap);
} else { // Step 1 failed
// log and handle
}
}
/**
* Explain what step2 does.
*/
private void step2(Map<String, SomeObject> objectsMap) {
// Step 2
final AnotherObject anotherObject = anotherService
.createAnotherObject(objectsMap);
if (null != anotherObject) {
step3(anotherObject);
} else { // Step 2 failed
// log and handle
}
}
/**
* Explain what step3 does.
*/
private void step3(AnotherObject anotherObject) {
// Step 3 that gets anotherObject as input and returns something
// else
}这种方法只是将方法分解为较小的方法。优点是每一种较小的方法只对一件事负责。因为它是一种方法,所以可以向它添加javadoc。因此,不再需要内联评论了。最终,您可以给该方法更好的名称,并完全省略javadoc。
重构,以便使这些步骤在运行时中可替换
如果您想配置在运行时执行的步骤(例如,由于某些用户输入),则必须将它们封装在对象中,因为您的应用程序对可以替换的对象的引用。
因为您希望所有的步骤都有一个通用的api,所以必须使它更加通用。
从客户的角度开始思考。如何执行这些步骤。例如。
for (Step step : steps) {
boolean executeNext = step.execute();
if (!executeNext) {
break;
}
}设计一个Step接口
public interface Step {
boolean execute();
}如何将一个步骤的输出作为另一个步骤的输入传递给另一个步骤?
建立一个接口
public static interface StepInput<T> {
public T getInput();
}执行你的步骤。一个抽象的课程会帮助你。
public abstract class InputOutputStep<T> implements Step,
StepInput<T> {
private T returnValue;
protected void setReturnValue(T returnValue) {
this.returnValue = returnValue;
}
public T getInput() {
return returnValue;
}
}
public class Step1 extends InputOutputStep<Map<String, SomeObject>> {
private StepInput<Map<String, SomeObject>> stepInput;
public Step1(StepInput<Map<String, SomeObject>> stepInput) {
this.stepInput = stepInput;
}
public boolean execute() {
boolean executeNext = false;
Map<String, SomeObject> objectsMap = stepInput.getInput();
if (!objectsMap.isEmpty()) {
// Step 2
setReturnValue(objectsMap);
executeNext = true;
} else { // Step 1 failed
// log and handle
}
return executeNext;
}
}
public class Step2 extends InputOutputStep<AnotherObject> {
private StepInput<Map<String, SomeObject>> stepInput;
private AnotherService anotherService;
public Step2(AnotherService anotherService,
StepInput<Map<String, SomeObject>> stepInput) {
this.anotherService = anotherService;
this.stepInput = stepInput;
}
public boolean execute() {
boolean executeNext = false;
Map<String, SomeObject> objectsMap = stepInput.getInput();
AnotherObject anotherObject = anotherService
.createAnotherObject(objectsMap);
if (null != anotherObject) {
setReturnValue(anotherObject);
executeNext = true;
} else { // Step 2 failed
// log and handle
}
return executeNext;
}
}
public class Step3 extends InputOutputStep<Void> {
private StepInput<AnotherObject> stepInput;
public Step3(StepInput<AnotherObject> stepInput) {
this.stepInput = stepInput;
}
public boolean execute() {
AnotherObject anotherObject = stepInput.getInput();
setReturnValue(null);
return false;
}
}在运行时配置这些步骤并执行
Step1 step1 = new Step1(stepInput);
Step2 step2 = new Step2(anotherService, step1);
Step step3 = new Step3(step2);
Step[] steps = new Step[]{step1, step2, step3};
for (Step step : steps) {
boolean executeNext = step.execute();
if (!executeNext) {
break;
}
}发布于 2014-10-08 06:44:18
这个场景-where --您做了很多事情,如果其中任何一个失败,都希望中止和记录--这就是设计异常处理的目的。例如:
try {
// Step 1
Map<String, SomeObject> objectsMap = someService.createObjectsMap();
if (objectsMap.isEmpty())
throw new SomethingWentWrongException("Failed to get object map from service");
// Step 2
AnotherObject anotherObject = anotherService.createAnotherObject(objectsMap);
if(anotherObject == null)
throw new SomethingWentWrongException("Failed to create another object");
// Step 3 that gets anotherObject as input and returns something else
} catch(SomethingWentWrongException e) {
// log and handle
e.printStackTrace();
}理想情况下,someService.createObjectsMap和anotherService.createAnotherObject会抛出它们自己的异常,而不是让您检查返回值。那你只需要写:
try {
Map<String, SomeObject> objectsMap = someService.createObjectsMap();
AnotherObject anotherObject = anotherService.createAnotherObject(objectsMap);
// Step 3 that gets anotherObject as input and returns something else
} catch(Exception e) {
// log and handle
e.printStackTrace();
}(不过请注意,只有当您真正想要捕获所有故障时,才应该捕获Exception )
发布于 2014-10-08 10:32:18
选项:
谢谢,
https://stackoverflow.com/questions/26250321
复制相似问题