我正在使用全栈打字稿应用程序,并且正在尝试
但是在关系方面,我很难弄清楚如何设计这些模型。
现在我有一个core
软件包,可以导出一些接口
interface Item {
id: string;
text: string;
idProject: string;
}
interface Project {
id: string;
name: string;
idSource: string;
}
interface Source {
type: 'rss' | 'api';
name: string;
}
interface ItemService {
get(id: string): Promise<Item>
}
interface ProjectService {
get(id: string): Promise<Project>
}
interface SourceService {
get(id: string): Promise<Source>
}
interface ProjectItemLoaderService {
constructor();
loadItems(project: Project, source: Source): Promise<Item[]>;
}
然后在我的server
包中,我像这样使用它们
get('/project/:idProject/items', ({ idProject }) => {
const project = projectService.get(idProject);
const source = sourceService.get(project.idSource);
const items = projectItemLoaderService.loadItems(project, source);
...
})
但是从我一直在阅读的有关抽象性很强的模型(DDD,六边形体系结构)的主题来看,我的模型不应通过ID引用关系,而应包括实际模型,因为ID之类的东西存储概念,而不是域概念。
interface Item {
id: string;
text: string;
project: Project
}
interface Project {
id: string;
name: string;
source: Source
}
interface Source {
type: 'rss' | 'api';
name: string;
}
...
interface ProjectItemLoaderService {
constructor();
loadItems(project: Project): Promise<Item[]>;
}
...
get('/project/:idProject/items', ({ idProject }) => {
const project = projectService.get(idProject);
// Project already includes the Source model, not need to load it
const items = projectItemLoaderService.loadItems(project);
...
})
这更方便,因为不必不断加载嵌套模型,但是随着嵌套越来越深,它似乎很容易失控。 Project模型实际上应该具有一个items: Item[]
属性,这可能需要很长时间才能基于后备存储进行填充。然后它将是周期性的,这是另一个问题。
我基本上是在寻找有关创建与数据无关的模型的建议,以及应该如何为处理这些模型的服务提供访问其关系的建议。也许在没有完整的DDD(用例,命令等等)的情况下做这种事情不是很可行,我应该只使用源耦合的ORM对象,但是我确实很喜欢拥有业务逻辑层的想法与底层数据源分离。
答案 0 :(得分:0)
首先:是的,最好有一个域对象图而不是具有ID的地图。操作,理解和实现关系以及维护起来要容易得多。
第二:您不得在应用程序中加载域的全部数据。而且,在加载对象时,您不必加载整个依赖关系树。
->使服务仅加载页面或操作所需的对象和嵌套对象。
例如,对于列表,您通常通常只需要加载列表中的对象,但是在详细信息页面上,您将需要加载并显示关联的子级,深度为1或2级以上。
(您稍后将考虑哪些数据可能经常重复使用并使用缓存进行优化)