域模型/存储库中的下拉列表


Drop-down list from Domain Model / Repository

我希望在我的系统中轻松创建从数据库填充的下拉菜单(例如,用户组列表)。对于这个系统,我通常遵循领域驱动的设计方法,包括Repository模式的稍微修改的版本。(系统使用PHP)

由于检索给定域对象类的下拉列表是一种常见操作,我想知道在相关存储库上创建getDropDownList()方法是否合适。

例如,假设所讨论的领域对象称为"Category"。我提议的是创建一个CategoryRepository::getDropDownList()方法,该方法将返回类别id和标题的关联数组,准备用于创建HTML <select>列表。

在过去的一个项目中,当我在一个类似存储库的类上创建一个getDropDownList()方法时,另一个开发人员说这样的方法不属于那个类,说它更多地与视图而不是模型有关。但我不这么认为,因为该方法的目的只是返回列表的原始数据。它甚至不需要用来创建一个下拉列表;它可以被转换为JSON数据或任何其他数量的东西。

我的主要问题是:

  1. 像我描述的getDropDownList()方法属于存储库类吗?如果不是,它应该去哪里呢?
  2. 这可能只是一个命名问题吗?如果我把它称为getSimpleList()getArrayForList()之类的东西,以表明它返回一个数组,而不是已经呈现的HTML,也许会更好?

继续这个类别的例子,这个方法返回的数据将返回一个关联数组,其中类别id作为键,类别名称作为值,例如:

array(
    1 => 'Category A',
    2 => 'Category B',
    ...
)

我认为您应该寻找每个程序元素的业务含义。视图层的存在只是为了表示业务规则/数据,并且应该易于替换。另一方面,您的存储库是业务模型的一部分,应该明确遵循业务命名(业务人员可以理解的名称)。因此,您建议的方法命名是无效的。"DropDownList", "SimpleList"answers"ArrayForList"对业务主管没有任何意义。

我建议如下:

  • 按书路径(如果性能不是问题)将是方法CategoryRepository::findAll()/getAll(),它以Category实例的形式返回所有类别-这种方式您正在处理跨所有层的严格业务元素,这非常好,因为您不引入任何中间类型。在视图层,你可以很容易地将实例格式化为<option/>元素
  • 自定义方法(如您所建议的),但具有商业ppl可以理解的名称-例如getTitlesOfAllCategories()(@返回字符串[]类别ID的数组=>标题)

getDropDownList()的另一个问题是,它不能"回收"容易,因为命名问题-想象一下突然需要在<ul><li>列表中列出类别-是时候复制你的原始方法与get子弹列表()?:)关于复选框-也许getCheckboxList()?但是,意思总是一样的,你只是想呈现…ta-daaaam……

你应该尽你最大的努力而不是去查询你的域名。你的领域应该集中在完整的聚合/实体上。

应该创建一个单独的查询层,使用一些不可知的命名来专注于返回数据。

例如,在c#中,我会有这样的东西:

public interface ICategoryQuery
{
    DataTable All();
}

All方法这样的东西通常不会在CategoryRepository上找到,因为该域涉及操作数据(命令侧)。因此,如果我们经常需要对所有类别执行某些操作,以至于需要使用All方法,那么我们可能存在设计缺陷。仔细想想,这可能表明我们正在查询我们的域名:)