【问题标题】:How to apply Composition to share code between Struts2 Action classes如何应用组合在 Struts2 Action 类之间共享代码
【发布时间】:2011-09-26 17:37:59
【问题描述】:

如果您使用继承并将所有公共代码和属性放入基类中,则在 Action 类之间共享代码很容易。作为最佳实践,我认为经验法则是prefer composition over inheritance。不过,我发现将这个概念应用于 Action 类非常困难。也许我做得不对。

例如,我有 3 个不同的 Action 类。它们都处理用户注册的不同方式(用户可以从多个表单注册)它们最终都调用相同的服务方法并且需要以相同的方式处理错误。通用代码类似于:

public class RegisterAction1 {

    public String execute() {

         ...Leaving out code here....

        try {
            registrationService.register(user);
        } catch (BusinessException e) {
            if(e.getErrors().containsKey("someError3)){
                return "Case1";
            }
            else if (e.getErrors().containsKey("someError1")) {
                session.put(Constants.SESSION_REGISTERVO, registerVO);
                return "Case2";
            } else if(e.getErrors().containsKey("someError2")) {
                this.addFieldError("aliasName", this.getText("some.error"));
            } else if(ce.getErrors().containsKey("someError3")) {
                this.someFieldThatMustBeSetForView1 = true;
                this.someFieldThatMustBeSetForView2 = true;
                this.addFieldError("addressLine1", null);
                this.addFieldError("addressLine2", null);
                this.addFieldError("city", null);
            }
        }

        ...Leaving out code here....

        return "Success";
    }
}

要使用组合,我认为您会将这段逻辑移动到“Helper”类中,并在 Action 类中引用该 Helper。如果您要在实现此公共代码的此帮助程序类中创建一个“callService”方法,您将如何处理很多代码实际上正在修改类上的字段这一事实......即,您是否传递了对像下面这样的辅助方法的动作?如果是这样,您如何处理它可能是三个不同动作类之一(即 RegisterAction1、RegisterAction2、RegisterAction3)的事实?

public String callService(RegisterAction1 registerAction) {

【问题讨论】:

    标签: java design-patterns struts2


    【解决方案1】:

    有很多方法可以做到这一点。

    但是,如果有非动作类需要修改动作数据,我可能会选择ModelDriven 方法,并传递模型,将其与 S2 架构解耦(假设您的动作扩展 ActionSupport )。

    在您的情况下,您还直接修改了字段错误(这只是一张地图)。天真的(并且可能足够好)的方法是要么只是传递它,要么传递 back 一些可用于修改字段错误的东西,无论是在拦截器中,还是在基本动作类方法。或者,如下面的选项,假设可以访问 ValidationAware impl(以及模型或 ModelDriven impl)。

    另一种选择是将相关部分封装在接口中,因此传递给助手的唯一内容是接口实现。如果您想直接访问字段错误映射,这也可能包括 ValidationAware

    这两种解决方案还解决了“不同类型的注册操作”问题,除非它们完全不同。如果是这样,我会考虑保持原样 - 不必要地过度设计某些东西是没有意义的。

    【讨论】:

    • 太棒了,我认为 ModelDriven 可以真正帮助解决我面临的一些问题。一般来说,您认为通过 Base 操作类共享代码是可行的设计吗?
    • 取决于共享的代码类型,我想。有时我会从动作类中的一堆共享代码开始,如果它实际上不属于 Web 层,则最终将其移出。当它是 web 层、特定于应用程序的代码时,当然——我从来没有超过 2 层深的动作层次结构。如果它是 corporation 特定的代码,我可能会重新考虑,但这通常也会以相对较胖的基本动作类结束。
    猜你喜欢
    • 2018-05-25
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    • 2019-07-03
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多