领域模型和它的实现是有区别的。仅仅因为您的模型显示了关系Person ---> Campaign ---> Event 并不意味着您必须以这种方式实现它。 IOW,您的模型以面向对象的方式展示了您的分析和设计,但您在 OOP 中实现该模型,它在代码中复制该模型的能力受到限制。
考虑以下内容。
Person 不是由其对Campaign 的所有权定义的,因此可以将活动排除在其知识责任之外。另一方面,Campaign 由作为其执行的一部分发生的Events 定义,因此在活动中拥有一系列事件是公平的。我要说的是,每个班级都应该有足够的行为和知识来使其完整。
关于域和持久层之间的通信,将它们视为两个非常不同的系统,彼此不关心。他们每个人都知道自己的职责和发布的公告。例如,持久层知道如何持久化传递给它的数据并宣布数据已保存。但是,持久层不一定需要了解领域对象。同样,领域层理解Person、Campaign和Event,但对持久性一无所知。
上面的意思是领域层需要自己是一个整体,不应该依赖持久层来获取数据。但是,它仍然需要提供数据以履行其职责。该数据可以来自用户界面或数据库,并通过了解域和持久层的第三方传递给它。
所以,在代码中(伪 C#)...
namespace DomainLayer
{
interface IDomainListener
{
void PersonCreated(Person person);
}
class Person
{
private string name;
public Person(string name)
{
this.name = name;
}
public string Name
{
get { return name; }
}
}
class Domain
{
private IDomainListener listener;
public Domain(IDomainListener listener) {
this.listener = listener;
}
public void CreatePerson(string name) {
Person person = new Person(name);
listener.PersonCreated(person);
}
}
}
namespace PersistenceLayer
{
interface IPersistenceListener
{
void PersonDataSaved(int id, object data);
}
class Persistence
{
private IPersistenceListener listener;
public Persistence(IPersistenceListener listener)
{
this.listener = listener;
}
public void SaveData(object data)
{
int id = ...; // save data and return identifier
listener.DataSaved(id, data);
}
}
}
namespace MyApplication
{
class MyController : IDomainListener, IPersistenceListener
{
public void CreatePersonButton_Clicked()
{
Domain domain = new Domain(this);
domain.CreatePerson(NameTextbox.Text);
}
public void PersonCreated(Person person)
{
Persistence persistence = new Persistence(this);
persistence.SavePersonData(person.Name);
}
public void DataSaved(int id, object data)
{
// display data on UI
}
}
}
如您所见,命名空间代表不同的层。 XYZListener 接口定义由XYZ 层发出的公告。对这些公告感兴趣并将对其作出响应的任何其他层都需要实现这些接口,我们的MyApplication 层也是如此。
当点击“创建按钮”时,控制器为域层创建Domain外观对象并将自己注册为监听器。然后它调用CreatePerson 方法,该方法实例化Person,然后宣布这已经完成,并传递新实例。控制器在PersonCreated 实现中响应此公告,其中它产生持久层的外观并再次将自己注册为侦听器。然后它调用SaveData 方法,该方法在完成时通知DataSaved。然后,该方法的实现会在 UI 上显示数据。
如你所见,领域层和持久层都只知道自己,不关心对方的职责。将两者连接在一起的是应用程序逻辑,这里表现为控制器。
回到你的具体问题,你可以有一个关于持久性的方法FindPerson,它将宣布PersonFound(int id)。控制器的响应是调用持久层来检索有关活动和事件的数据,然后使用该数据调用域层来构建Person。
抱歉,回答太长了……