类设计:索引列表还是几个属性?

时间:2009-07-31 14:15:53

标签: oop domain-driven-design

我在课堂设计中不时碰到这个...当我在对象中有几个相同类型的属性时。举几个例子:

用户有几个地址。我们可以做到

IDictionary<string, Address> Addresses; // Addresses["BusinessAddress"];

Address BusinessAddress; 
Address ShippingAddress;

产品有相关产品,由不同的笼子。我们可以做到

IDictionary<string, IList<Product>> Related; // Related["Available"];

IList<Product> Available;
IList<Product> Required;

用户分配了多个角色。我们可以做到

IList<Role> Roles;

bool IsAdmin;
bool IsSales;

那么,什么更好? IDictionary更灵活,因为我们可以轻松地将新地址类别添加到数据库中,甚至无需触及代码。但缺点是我们使用字符串来访问;这总是容易出错。我们可以用单元测试或常量来解决这个问题,比如

public class ProductCategories { public static string Available = "Available"; }

但是,阅读“product.Available”比“product.Related [ProductCategories.Available]”更糟糕。

还有其他一些注意事项,例如,使用ORM(例如NHibernate)更容易/更好地映射。

但问题是,有没有已知的偏好?设计有关此主题的文章和/或书籍?这里的人们经历过现实世界的实践吗?

例如,我们可以结合两个世界......让IList和bool IsAdmin做“返回Roles.Contain(角色(”管理员“));”。但这看起来很难看。

或者,对于IDictionary,我们每种类型的地址不能超过1个;如果我们这样做

IDictionary<string, IList<Address>>

对于我们不需要倍数的简单地址,这很疯狂。但是如果我们使用BillingAddress,ShippingAddress和IList for MultipleAddress,我们可以对我们的地址进行更精细的控制......使用Intellisense等等。

2 个答案:

答案 0 :(得分:1)

由于您提及域驱动设计(DDD),the book of the same title包含意图显示接口的指南。拥有域对象的命令绝不是故意揭示的,所以仅仅因为这个原因,我强烈建议不要使用字典。

字典应主要用于公开API,其中调用者可以添加和检索值,或者用于非常通用的基础结构API,您需要能够处理非常灵活的情况。

DDD不是这种情况。想象一下,您没有自己编写类,然后在示例中包含了基于Dictionary的Addresses属性。你怎么知道它包含哪些类型的地址?您必须查看实现代码或阅读文档。

另一方面,如果您同时拥有BusinessAddress和ShippingAddress属性,那么API的消费者可以立即看到可用的内容。

我认为您考虑的灵活性是一种错误的灵活性,因为客户端代码仍然需要知道哪些字典条目可用之后才能使用它们。向类添加新属性就像向字典添加条目一样容易。

如果你真的需要一个Dictionary(或更好的,一个列表),因为有时你需要遍历所有地址(或其他),你可以通过暴露一个只读属性来实现这一点,该属性为两者提供一个枚举器 - 比如这样:

public Address BusinessAddress { get; set; }
public Address ShippingAddress { get; set; }

public IEnumerable<Address> Addresses
{
    yield return this.BusinessAddress;
    yield return this.ShippingAddress;
}

答案 1 :(得分:0)

这取决于。如果您的应用程序需要允许用户添加地址,那么请务必使用Address es字典。