如何在控制器中实现策略模式

时间:2011-12-19 09:17:54

标签: java design-patterns strategy-pattern

我正在尝试为我的程序的控制器组件实现策略模式。

我有不同的视图状态,例如CreateViewState,您可以在空白画布上创建项目,因此它需要像createInput()addToModel()stuff这样的方法。

我拥有的另一个状态是EditViewState,您可以在其中编辑以前添加的项目。您选择一个输入,然后更改其颜色或大小或其他。因此控制器需要的方法是selectInputAtLocation(),或changeColor(java.awt.Color color)changeSize(int size) ...

我的方法是创建一个IController接口,它有一些常见的方法,比如repOK(),toString(),还有一些像thisWasTheLocation(int x,int y),视图静态调用它来传递按下的位置在屏幕上给控制器。

然而,为了完成他们的特定工作,我没有他们拥有的常用方法。我在考虑在接口中放置一个doStuff(Item item)方法,然后在那里执行控制器逻辑,这样客户端代码就可以在整个代码中使用IController.getInstance().doStuff(item)。据我所知,如果我调用它们具体的方法(changeColor()用于editController,createInput()用于createController),我将需要转换控制器。

如果我在界面中创建一个doStuff()方法,那么我需要实现很多if语句,尤其是对于editController(它有超过7-8种方法,我没有提及)。

如何设计整个系统?

P.S:Controllers是单身,因此是getInstance()

1 个答案:

答案 0 :(得分:0)

很难从你的描述中说出来,但听起来你正在编写自己的MVC框架。为什么不使用Spring,Struts或类似的?目前尚不清楚您的域模型有多复杂。

简要问题如何设计整个系统?可能最好通过使用众多现有Java MVC框架之一来解决

良好的设计鼓励您将任何棘手的业务逻辑(doStuff())移出控制器并进入服务层。您的代码将更容易测试,而不是与您的控制器绑定。

当你声明所以控制器需要的方法是selectInputAtLocation(),或者changeColor(java.awt.Color color)或changeSize(int size)...... 这听起来像你一样在不需要的地方增加复杂性。

使用Struts作为示例,您的HTTP表单POST将包含用户已编辑的数据,这可以在ActionForm bean中的Controller中使用。然后在决定调用哪种Service方法之前验证/清理此用户数据(类似于您询问的策略模式)。

关于您的Contoller设计,您可以为每个域模型类设置一个Controller类,如此

public class ThingDispatchAction extends DispatchActionSupport {

    public ActionForward read( ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp)
        // call service layer to read a Thing.java
    }

    public ActionForward edit( ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp )
        // call service layer to update a Thing.java
    }

    public ActionForward create( ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp)
        // call service layer to create a new Thing.java
    }

    public ActionForward save( ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp)
        // call service layer to persist a Thing.java
    }

    public ActionForward delete( ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp)
        // call service layer to delete a Thing.java
    }
}

或者你可以为每个域对象设置多个Controller类,这样每个类中只有一个方法,如下所示

public class ThingReadAction extends ActionSupport {

    public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp)
        // call service layer to read a Thing.java
    }
}

public class ThingDeleteAction extends ActionSupport {

    public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse resp)
        // call service layer to delete a Thing.java
    }
}

etc ...

选择的MVC框架将具有确定调用哪些方法的配置等。