域模型和用户界面

时间:2012-02-11 16:31:36

标签: java user-interface domain-driven-design domain-object

我不确定我是否应该直接在用户界面中使用域对象。例如,我希望为域实体用户设计用户界面,用户具有用户ID,名称,密码和角色列表。实体的设计使其永远不会处于无效状态(例如无效密码或空userId)

public class User {
    public User(String userId, String name, String password) {
        //Initialization and validation
    }

    public String getUserId {
        /*implementation*/
    }
    public void changePassword(String oldPassword, String newPassword) {
        /*Set new password if it complies with the rules
        and if the the old one is correct*/
    }

    public void setName(String Name) {
        /*implementation*/
    }
    public String getName() {
        /*implementation*/
    }

    public List<Role> getRoles() {
        /*implementation*/
    }

    public void addRole(Role role) {
        /*implementation*/
    }
}

设计用户界面最合适的方法是什么?

1)坚持域模型:设计3个窗口。窗口&#34;新用户&#34;使用给定的userId,名称和密码创建新用户。另一个窗口&#34;更改密码&#34;更改密码和另一个&#34;修改用户&#34;它允许您修改现有用户的名称和角色

2)可能需要仅使用一个窗口来创建具有给定userId,名称,密码和角色列表的用户。即使我还没有键入userId,我也应该可以添加角色。

选项1是最容易实现的,因为我可以直接在用户界面中使用域对象。但是用户界面可能会导致使用痛苦。 选项2是可取的,但域objets不能直接使用。如果尚未创建用户,我不知道如何添加角色。我无法创建用户,因为我当时可能没有正确的信息,例如表示userId的临时空文本框。我怎样才能做到这一点?

我能想到的唯一干净的解决方案是创建在用户界面中使用的类,这些类将模仿真实域对象中的信息。所以我将能够创建一个空的User来添加Roles,然后设置userId。用户界面可以使用该信息来创建真实域对象。

有一个简单的方法吗?这通常如何管理?

2 个答案:

答案 0 :(得分:1)

这是很多问题,但是当你开始研究如何在层之间传递对象时,你是正确的,因为它们是至关重要的。

让我们从

开始
  

“这通常如何管理?”

您正确地指出,您希望向用户呈现域对象的方式并不总是原始形式 - 有时您希望显示的内容少一些,例如在添加角色的用户示例中可以在与用户创建/修改不同的UI中,有时您想要显示更多,并排显示2个对象,或者例如显示来自2个对象的混合数据。

顺便说一下:你认为选项1(多个窗口)更多地贴在域模型上,而我认为它往往会模仿模型,因为它不会将整个域对象呈现在单个模型中屏幕 - 但这是一个细节。

那么你通常如何应对呢?正如你所说的那样 - 通过创建为你的观点量身定制的特定于UI的对象

  

我能想到的唯一干净的解决方案是创建要使用的类   将模拟真实域中信息的用户界面   对象。因此,我将能够创建一个空用户来添加角色   之后设置userId。

这些通常被称为DTO,.NET / MVVM世界中的ViewModel对象等。

  

用户界面可以使用该信息来创建真实域   客体。

通常,从UI对象创建/更新域对象不是UI本身的责任。映射在另一层完成。

现在我们已经看到了基本解决方案,让我们看看它是如何异常管理的;)

有一些替代方案。其中之一是Naked Objects模式,其中所有用户界面都是域对象的直接表示。这大大简化了问题,但是在工作流程和易用性方面,这些UI总是最好的还有待观察。

或者,您可以在表示层中使用域对象。这个recent post指出了当您对同一个对象进行多次表示时发生的问题,并检查了在所有层中使用相同域对象的可能性。这里的问题是你可能不得不强迫一些数据进入你的域对象,而这些数据并不是纯粹与域相关的,你可能也必须放弃一些不变量(例如,“如果没有附加角色,用户就不能存在) “,如果您将用户创建和角色分配用户界面分开。”

最后,回到用户/角色示例并且“如果尚未创建用户,我不知道如何添加角色”:您不必为最终用户提供现有的User对象您的应用程序能够选择角色。您可以在屏幕上选择角色并保留它们,直到完成User对象的实际实例化,并仍然强制执行所有必需的字段,例如ID。

答案 1 :(得分:0)

选项2有什么问题?您可以先创建一个新的User对象,然后向其中添加规则。如果您没有创建新用户对象的所有必要信息(例如,空用户标识文本框),而不仅仅是向用户发出必须填写此字段的通知。