2013-06-20 18 views
0

我想让我的系统中的数据库(例如,用户组列表)(例如用户组列表)(例如,用户组列表)更容易创建下拉菜单。我通常遵循这个系统的领域驱动设计方法,包括稍微修改版本的Repository模式。 (该系统使用PHP。)Domain Model/Repository的下拉列表

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

例如,假设有问题的域对象被称为“类别”。我建议的是创建一个CategoryRepository::getDropDownList()方法,该方法将返回一个关联的类别ID和标题数组,准备用于创建一个HTML <select>列表。

在过去的项目中,当我在一个类库中创建了一个getDropDownList()方法时,其他开发人员之一表示,这样一种方法不属于该类,并且说它比视图更重要,该模型。但我不这样看,因为该方法的目的仅仅是返回列表的原始数据。它甚至不需要用来创建下拉列表;它可以转换为JSON数据或任何其他数量的东西。

我的主要问题是:

  1. 难道一个getDropDownList()方法,就像我在一个仓库类属于所描述的?如果不是,它应该去哪里呢?
  2. 这可能只是一个命名问题吗?如果我把它称为getSimpleList()getArrayForList()来表明它返回一个数组,而不是已经呈现的HTML,那么也许会更好一些?

要继续的类实例,从这个方法返回的数据将返回类别ID的关联数组作为键和类别名称为值,例如:

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

我会选择选项2,渲染下拉是视图的作业 – Orangepill

+0

@Orangepill,只是好奇,你会怎么说呢?我刚刚提出了'getArrayForList()',这正是我目前所倾向的。 –

+0

或者可能类似getNames – Orangepill

回答

1

恕我直言,你应该寻求一个业务含义的每个程序元素。视图层仅仅是为了呈现业务规则/数据,并且应该易于替换。另一方面,您的存储库是商业模式的一部分,并且一定要遵循商业命名(商业人士可以理解的名称)。因此,您建议的方法命名无效。 “DropDownList”,“SimpleList”和“ArrayForList”对业务负责人没有意义。

我建议如下:

  • 由这本书路径(如果性能是不是一个问题)是方法CategoryRepository ::的findAll()/ GETALL()返回所有类别分类的形式实例 - 通过这种方式,您正在严格处理所有图层中的业务元素,这是非常好的,因为您没有引入任何中间类型。在视图层中,您可以轻松地将此实例格式化为<option/>元素
  • 自定义方法(如您所建议的),但名称可以被商业人员理解 - 例如getTitlesOfAllCategories()(@返回字符串[]类别ID =>标题的阵列)

与getDropDownList(另一个问题)是它不能被命名问题的容易因为“回收” - 想象的突然需要<ul><li>列表中的列表类别 - 是时候用getBulletedList()复制你的原始方法了么?复选框怎么样 - 也许getCheckboxList()?但是,意思总是一样的,你只是想提出... ta-daaaam ... 所有的类别

+0

关于“商业意义”的好处...我的犹豫与你的“书”路径是,PHP的每个请求生命周期,我会检索一堆字段不必要的,但它可能是不成熟的优化要关心的是(加上总是缓存)。 'getTitlesOfAllCategories'不太准确(尽管可能已经足够接近了),因为我也在检索这些ID - 我在应该返回什么数据的问题的最后添加了一个示例。 –

+0

我猜你会打消我上面评论中提到的'getKeyValueArray()'的想法,因为它没有商业意义?如果我在视图层中创建了一个方法来构造接受键和值字段名的下拉列表,我想我可以用findAll/getAll方法完成类似的事情。: '$ categories = $ categoryRepository-> getAll(); createDropDownList($ categories,'id','name',... [other options] ...);' –

+0

关于本书的方法,是的 - 这将是一个缓存问题(例如,Doctrine 2自动处理它只是抛出足够的RAM)。缺少身份证问题是我的错字,我真的想写“@return string [] ID =>标题数组” – gseric

0

你应该尽你最大的努力而不是来查询您的域名。你的域名应该专注于完整的聚合/实体。

而是创建一个单独的查询层,专注于使用某些不可知名称返回数据。

例如,在C#我想有这样的事情:

public interface ICategoryQuery 
{ 
    DataTable All(); 
} 

All方法的东西是不是你通常会发现在CategoryRepository作为域涉及操纵数据(命令 - 侧)。因此,如果我们需要在全部上执行一些操作,并且保证采用All方法,我们可能会遇到设计缺陷。想想,这可能表明我们正在查询我们的域:)

+0

您是否在谈论CQRS而不是传统的DDD? Fowler和Evans都将查找器/查询方法描述为存储库的主要特征之一。但是,让我们说,我有你所建议的单独的查询类;它仍然给我带来了同样的问题 - getDropDownList或getArrayForSelectList方法属于这样一个Query类吗?该方法不能被称为'全部',因为我需要指出只有ID和标题字段将从数据库中被选中; 'all'听起来像它会返回一个完整的对象列表。 –

+1

CQRS实际上不是DDD的一种形式:) ---但是,它是CQRS,它可以按照您的喜好简单或复杂地应用。事物的查询方面并不关心域对象。如果你真的需要读取模型(DTO),你可以沿着这条路线走下去。只是很多映射,但它将取决于它购买你的东西。无论你喜欢什么,你都可以调用你的方法并返回你喜欢的任何东西如果你需要一个更具描述性的名字,那就这样吧,但是我没有任何UI特定的位,所以没有'DropDown'或'Select'。但是,这只是我:) –

+0

谢谢... CQRS与DDD是一个单独的讨论,但它听起来像你说,它确实有意义的方法放在某种查询对象而不是别的地方。现在我只需要决定怎么称呼它......也许“getIdsAndNames”?我不知道如何在没有“下拉”或“选择”的情况下将其命名。 –