我有一台简单的状态机,现在受到很多特殊情况的干扰。
最初:
void state(SomeObject o) {
doStep1();
doStep2();
doStep3();
}
现在,someobject有一个名为type的字段 - 比如typeA,typeB,typeC。 typeC需要一些特殊的处理。
void state(SomeObject o) {
doStep1();
doStep2();
if (o.type == typeC) { o.doFoo(); }
doStep3();
if (o.type == typeC) { o.doFoo(); }
}
显然,这段代码不可扩展且易碎。我有一个名为typeD的第四种类型,它只会添加更多的if-elses。在这种情况下使用哪种模式?如果我使用多态,假设一个接口SomeObject,它有4个类型A B C和D的实现,我担心A和B会有doFoo()的空实现,这是不好的。有什么好的设计模式?
答案 0 :(得分:4)
state
逻辑正如您已表明的那样不灵活。例如,如果某些对象需要以不同的顺序执行操作(3-> 1> 2),问题会变得更加复杂。
由于行为主要取决于SomeObject
类型,我相信一种“干净”的方法是将每个对象转换为一组可组合命令(命令模式+复合/装饰器)。
/* Declare an interface for executing an operation */
public interface Command
{
public void execute();
public Command setNext();
public Boolean hasNext();
}
/* Abstract class providing compose-ability and chaining behavior for its children.
*/
public abstract class BaseCommand implements Command
{
private Command next;
public Boolean hasNext()
{
return next != null;
}
public Command setNext(Command nextC)
{
next = nextC;
return nextC;
}
public void execute(){
executeImpl();
if(hasNext()) next.execute();
}
public abstract void executeImpl();
}
现在,您可以定义一组与特定处理相对应的命令(每个命令将直接映射到状态方法的特定“行”/步骤)。
public class Step1Command extends BaseCommand
{
// If we need access to the SomeObject instance we can define a dependecy on it
// ex. through a constructor
//The necessary processing goes here
public void executeImpl(){
doStep1();
}
}
最后,您需要将对象转换为一组命令,这可以通过工厂类来实现:
public class CommandFactory
{
//The necessary processing goes here
public Command create(SomeObjectA typeA){
Command firstCommand = new Step1Command(typeA);
Command secondCommand = new Step2Command(typeA);
//....
Command lastCommand = new StepXCommand(typeA);
//We can easily switch the order of processing for a particular object
fistCommand.setNext(secondCommand)
//...
.setNext(lastCommand);
return firstCommand;
}
}
现在如何查看代码?
CommandFactory cFactory = new CommandFactory();
void state(SomeObject o) {
Command command = cFactory.create(o);
command.execute();
}
那么,增加的价值是什么(因为这可能看起来像是一种矫枉过正的行为)?
取决于对象类型的处理远离state
方法。方法重载+继承应该允许你绕过if / elses。
您可以轻松切换必要处理()的顺序,从而使逻辑更加灵活。
添加新的SomeObject实现处理不会改变现有代码(可维护性+可扩展性)