说,我正在制作一个带有用户界面的游戏,我希望在画布上绘制某些人物,比如用它们上面的矩形来表示它们,这是一个具有该人物特定名称的文本框。纯粹从域的角度来看,我的人有一个名字。如有必要,可以添加以后的特定域逻辑
public class Person{
private String name;
//Constructor and methods
}
我还需要跟踪有关此人的Ui信息,因此我决定制作一个单独的课程。
public Class PersonUi {
private int x;
private int y;
private int length;
private int width;
//Constructor and methods
}
现在我有不同类的Ui和域数据。假设我想在点击某个人时知道该人的姓名。我可以链接正确的PersonUi对象,但我怎么知道这个人的名字?如何将Ui和域数据尽可能地面向对象?
e.g。考虑到良好的面向对象设计,如何遵循以下选项?
1)保存在另一个类中的列表中并使用列表的顺序来知道哪个ui对象属于哪个域对象
2)使用Map映射两个类
3)使用包装类来包装这两个类。
或者仅仅在1个类中定义上一个示例中的所有数据是否可以?
答案 0 :(得分:1)
通常,在UI和域之间使用service / api层可以解决此问题。您可以在personUI中存储您的人员ID(让他们说GUID)。然后在UI类中,您可以:
public class PersonUi
{
private Guid personId; // Or UUID for java
private IPersonService personService;
...
nameTextBox.text = personService.getPersonName(personId);
}
这样,您就无法从UI端直接链接到您的域。所有用例必须通过服务进行传递。
当然也可以使用此服务来改变域名。
要测试设计的完整性,您可以将域放在不同的包/项目中,并将其作为UI层的依赖项完全删除。 UI层可以引用可以引用域层的服务层。
要将对域所做的更改传达给UI,您可能需要查看事件系统。如果一个输入组件接收到更改域的输入,并且这些更改必须传播到其他几个UI组件,则事件可能是最佳方式。只需确保在事件args中提供最少量的信息,而不是实际的域实体,因为这将使您回到最初关注UI和域的关注。
UI组件的最终代码可能如下所示(原谅我的肮脏C#约定):
public class PersonUi implements IPersonNameChangeListener
{
private Guid personId; // Or UUID for java
private IPersonService personService;
...
public void userEnteredANewNameThroughUI(String newName)
{
personService.setName(personId, newName);
}
@Override
public void onPersonNameChange(Guid personId, String newName)
{
if(this.personId != personId)
return;
nameTextBox.text = newName;
}
}
在最后一个代码示例中,您会注意到您的输入不会直接影响您的输出。相反,更改会冒泡到您的域,并通过事件传回您的UI层。这意味着您的输入和输出组件现在也是独立的。