1

我不确定我是否应该直接在用户界面中使用域对象。例如,我希望为域实体用户 User 设计用户界面,该用户具有用户 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个窗口。窗口“新用户”使用给定的用户 ID、名称和密码创建一个新用户。另一个窗口“更改密码”用于更改密码,另一个窗口“修改用户”允许您修改现有用户的名称和角色

2) 最好只使用一个窗口来创建具有给定用户 ID、名称、密码和角色列表的用户。即使我还没有输入 userId,我也应该能够添加角色。

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

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

有没有简单的方法解决这个问题?这通常是如何管理的?

4

2 回答 2

1

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

让我们从

“这通常是如何管理的?”

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

顺便说一句:您认为选项 1(多个窗口)更多地坚持域模型,而我认为它倾向于较少地模仿模型,因为它不会在单个屏幕中呈现整个域对象 - 但是这是一个细节。

那么你通常如何处理呢?正如您所说的那样-通过创建为您的视图量身定制的特定于 UI 的对象

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

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

用户界面可以使用该信息来创建真正的域对象。

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

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

有几种选择。其中之一是裸对象模式,其中所有用户界面都是域对象的直接表示。这大大简化了问题,但就工作流程和易用性而言,此类 UI 是否总是最好的还有待观察。

或者,您可以只在表示层中使用您的域对象。这篇最近的文章指出了当您拥有同一对象的多个表示时出现的问题,并检查了在所有层中使用相同域对象的可能性。这里的问题是,您可能必须将一些数据强制到与域无关的域对象中,并且您可能还必须放弃一些不变量(例如,“如果没有附加角色,用户就不能存在",如果您将用户创建和角色分配用户界面分开)。

Finally, to get back to the user/role example and "I do not see how can I add roles if the user is not created yet" : you don't have to have an existing User object for the end user of your application to be able to select roles. You could just have the roles selected on the screen and hold them until the actual instanciation of the User object is done, and still enforce all the required fields such as the ID.

于 2012-02-12T09:45:38.703 回答
0

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

于 2012-02-11T16:40:38.357 回答