【问题标题】:Design pattern for display DTO objects显示 DTO 对象的设计模式
【发布时间】:2023-03-23 18:20:02
【问题描述】:

我是设计模式的新手,我有以下需求:我有一组由 DTO 对象表示的事件,例如:LateEventDTO、RescheduleEventDTO 等。这些 DTO 对象中的每一个都有自己的一组属性。现在,我有一个名为 EventDTO 的抽象类,所有不同类型的 DTO 对象(如 LateEventDTO、RescheduleEventDTO 等)都扩展了 EventDTO。

我会将这些 DTO 对象之一传递给我的 ui 层(jsp 页面),它会检查它是什么类型的 DTO 对象。像这样:

if(event instance of Late){
  //handle late event and display it's content
}

else if(event instance of Reschedule){
   //handle reschedule event and display it's content
}

等等等等。

我想要的是让表示层忽略不同类型的 eventDTO 对象。它需要做的就是获取一个通用对象并显示它的内容。它不应该像我上面显示的那样明确检查它的类型。

对于这种情况,最好的设计模式是什么?

【问题讨论】:

  • 我会考虑策略模式
  • 你应该在 IMO 重新设计东西,这样你就不会遇到这个问题:你的 DTO 只有 1 个接口,所以你不需要检查的 instanceof。

标签: java design-patterns


【解决方案1】:

如果你有一个页面并且你想显示具有不同属性的不同类,你必须指定应该在 JSP 页面的哪个位置显示哪个属性。

一种方法是让 JSP 页面了解您在哪里有一些“始终显示”变量的对象,然后是您想要显示的某种“其他”属性列表。

问题是 - 如何将这些 DTO 映射到这个新对象中?构造函数是一个答案(是的,还需要一些手动工作)。

public class JspUndestandableClass(){    

    public JspUndestandableClass(LateEventDTO lateEventDTO){
        ....
    }

    public JspUndestandableClass(RescheduleEventDTO rescheduleEventDTO){
        ....
    }
}

然后您可以简单地在控制器中创建这些对象并将其传递给 JSP 页面。

PS : 设计模式展示了解决某些问题的好方法,但它们并不能拯救你自己(即在错误的用例中使用它们)并且它们不能涵盖所有情况。

【讨论】:

  • 如果你想渲染一个基本类型 EventDTO 的对象(你很可能想要),你仍然必须强制转换对象(使用之前的 instanceof 检查)来调用其中一个方法。
  • @user714965 - 你总是可以在上下文中创建 JspUnderstandableClass,在它被转换为 EventDTO 之前你知道类型。
  • OP 有instanceof 检查我假设类型未知。假设有一个来自您要显示的数据库层的List<EventDTO>。你会怎么做?
  • @user714965 - 他说“我会将这些 DTO 对象之一传递给我的 ui 层”。此解决方案显然不适用于祖先列表。
  • 重点是:您需要instanceof 才能知道您需要调用哪个方法。如果您知道类型,那么问题将是多余的。
【解决方案2】:

创建连贯的类,而不是 DTO

这将解决abstract class 多态性的误用。

扩展abstract class 是策略模式(see @Crazy Ninja comment)。 abstract class 而不是 interface 并没有减少它。

扩展抽象类的目的是使每个实例都可以被相同的处理。如果你必须弄清楚每个实例是什么类型,那何必呢?


如果下面的内容不能满足您的设计需求,您仍然需要制作连贯的类——做某事的类,而不仅仅是包含字段/属性。


附:这可能不是有效的 Java 语法。

您的代码应该看起来更像这样:

public abstract EventBase {
    // declare common properties here.

    public virtual void Handle () {
         // code to handle the properties.
         // maybe there is some behavior for the base properties.
    }

    // Depending on how you're going to display contents, you 
    // may want to override toString()

   public override string toString() {   
       // format the DTO thingies as needed.
   }
}

public class RescheduleEvent extends Eventbase {
    // define RescheduleEvent unique properties here


    public override string toString(){
        string whoAMI = base.toString();
        whoAMI = whoAMI + .....
        return whoAMI;
    }

    public override void Handle() {
        base.Handle():

        // do stuff
    }
}

// client code.
myRescheduleEvent.Handle();
myWhateverEvent.Handle();

// or

foreach( Eventbase anEvent in eventList) {
    anEvent.Handle();
    DisplaySomething(anEvent.toString());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-15
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多