这是“分析瘫痪”似乎已经站稳脚跟的场景之一,所以请指教!
项目
一个相当简单的汽车产品列表,其中包括零件引用、适合的车辆等详细信息。
前端是一个 asp.net MVC 应用程序。
后端是 SQL,使用 Subsonic 将产品投影到域对象中。
功能
我们的屏幕之一是产品详细信息屏幕。 ASP.NET MVC Controller 调用产品存储库来检索产品详细信息,将这些详细信息(通过一些自动映射到 viewModel)返回到 View 。
现在的杀手锏是我们有两个或三个 channel 进入网站,根据 channel 的不同,用户需要看到不同的零件编号。
例如,如果是零售 channel ,则零件编号与数据库中的零件编号相同,但如果用户通过贸易 channel 访问该站点,则零件引用的开头将替换为替代编号。
例如如果通过交易 channel 查看,0900876 将变为 1700876。
我正在努力的地方是决定在哪里封装关于部件引用(以及其他可能改变的细节)的“ channel 规则”。
我已经考虑过这些替代方案。
将逻辑直接写入域对象
在 产品 类我们可以有一个方法/属性来获取翻译的部分引用。
public string TranslatedPartRef()
{
if (this.Channel == "Trade")
{
return PartRef.Replace("0900", "1700");
}
else
{
return PartRef;
}
}
在这种情况下,Product 实例必须知道 channel ,这对我来说似乎是错误的。
将逻辑封装在另一个对象中
我们可以编写一个类来处理这部分引用翻译,或者创建一个 channel 包含此逻辑的类。
我不明白的是如何协调这两个类(class)。
如果 Controller 调用存储库来检索产品,那么它是否应该确定使用了哪个 channel 并翻译部件引用?如果是这样,我如何将带有翻译部分引用的产品发送回 View ?
还值得注意的是,这部分引用也必须出现在搜索结果和其他场景中,因此我认为它需要整齐地包含在某个域中。
最佳答案
我不是 C# 人,但我想我会用 Java 中的装饰器来解决这个问题。
假设您有一个产品接口(interface),那么您可以创建一个装饰器来管理部件号问题。
class Product implements IProduct {
public String getProductCode();
// etc
}
class ProductChannelDecorator implements IProduct
{
// constructor, like this in C#?
public ProductChannelDecorator(IProduct product, Channel channel) {
this.product = product;
this.channel = channel;
}
public String getProductCode() {
switch (this.channel) {
case Channel.RETAIL:
return this.decorated.getProductCode();
case Channel.TRADE:
return retailToTradeTransformer(this.product.getProductCode());
// etc
}
}
// etc
}
关于domain-driven-design - 贫血域模型或 "where to put logic",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1425749/