Asp.net 如何设计定制产品生成器
我正在开发一个应用程序,用于生成对汽车等产品的评估。 因此,当一辆汽车的模型被选中时,我需要向用户展示各种选项,选项可能在不同的组中,如车轮、座椅内饰、行李箱配件 根据组的不同,客户可以在该组中选择一个或多个选项;如果选择了某个选项-其他一些选项可能会被禁用;并非所有选项都适用于每个模型 因此,有几个规则需要为不同的组定义,以指示哪些组合是允许的,哪些是不允许的Asp.net 如何设计定制产品生成器,asp.net,database-design,e-commerce,Asp.net,Database Design,E Commerce,我正在开发一个应用程序,用于生成对汽车等产品的评估。 因此,当一辆汽车的模型被选中时,我需要向用户展示各种选项,选项可能在不同的组中,如车轮、座椅内饰、行李箱配件 根据组的不同,客户可以在该组中选择一个或多个选项;如果选择了某个选项-其他一些选项可能会被禁用;并非所有选项都适用于每个模型 因此,有几个规则需要为不同的组定义,以指示哪些组合是允许的,哪些是不允许的 我应该如何着手为此设计数据库?在我开发此应用程序时,是否有一种模式可以利用?我用以下结构解决了类似的需求,用您上面的术语重新编写: 部
我应该如何着手为此设计数据库?在我开发此应用程序时,是否有一种模式可以利用?我用以下结构解决了类似的需求,用您上面的术语重新编写: 部分 组 汽车 并附上以下注释: 零件本身是独立的,每个零件都有零件号。 汽车模板本身是独立的。 可以将零件添加到选项组中,并且许多选项组属于一辆汽车。 没有汽车,选项组无法存在。 一个组可以依赖于另一个组 我需要防止循环引用 在编写类代码测试驱动开发之前,我首先编写了测试用例来处理我的模型,这给了我C语言的代码:
var dieselEngine = new Sku("diesel 2_litre,",1000);
var petrolEngine2 = new Sku("petrol_2_litre",800);
var petrolEngine25 = new Sku("petrol_25_litre",900);
var petrolTurbo = new Sku("petrol_turbo",2000);
var dieselTurbo = new Sku("diesel_turbo",2000);
var car = new Car("myCar");
car.AddGroup("Engines");
car.AddSkuToGroup("Engines", diselEngine);
car.AddSkuToGroup("Engines", petrolEngine2);
car.AddSkuToGroup("Engines", petrolEngine25);
car.AddGroup("Turbos");
car.AddSkuToGroup("Turbos", petrolTurbo);
car.AddSkuToGroup("Turbos", dieselTurbo);
car.SetRequirement(diselEngine, dieselTurbo);
car.SetRequirement(petrolTurbo, petrolEngine2);
car.SetRequirement(petrolTurbo, petrolEngine25);
我将dependency选项添加到组上,而不是Sku上,因为一个零件可能存在于多辆车上,但可能对每个特定的车有不同的依赖关系
我必须将所有内容都放在根car对象中,它将检查并强制执行我的所有业务规则,例如检查循环引用并防止循环引用
如果通过car对象进行的所有访问都感觉笨拙,您可以始终让car.AddGroup函数返回一个组,以使代码更易于阅读:
var engines = car.AddGroup("Engines");
engines.AddSkuToGroup(diselEngine);
engines.AddSkuToGroup(petrolEngine2);
engines.AddSkuToGroup(petrolEngine25);
但是不要忘记,业务规则只能由汽车强制执行,因为汽车可以看到所有组件。因此,我们总是通过根链接:
class ConfigurableProduct
{
List<Group> groups = new List<Group>();
Group NewGroup(string name)
{
var group = new Group(this, name);
this.groups.Add(group);
return group;
}
bool ContainsSku(string skuId)
{
foreach (var group in this.Groups)
{
if (group.ContainsSku(skuId))
return true;
}
return false;
}
}
class Group
{
Group(ConfigurableProduct parent, string name)
{
this.parent = parent;
this.name = name;
}
string name;
List<string> skuIds = new List<string>();
ConfigurableProduct parent;
void AddSkuToGroup(string skuId)
{
// enforce invariants via parent, call functions as reuqired
if (this.parent.containsSku(skuId))
throw new Exception("SKU already exists in this configurable template, cannot exist twice");
// do other things, like check circular references etc, all via this.parent
}
bool ContainsSku(string toFind)
{
foreach (var skuId in this.skuIds)
{
if (skuId == toFind)
return true;
}
return false;
}
}
对于实际的数据库存储,我最后会担心持久性,它可能是一个文本文件,MSSQL数据库,MySQL数据库,MongoDB,有很多选择
我发现专注于如何在我的应用程序中使用代码总是很有用的,而不是数据库需要如何使用的细节,因为存储可以通过存储库接口进行抽象,该接口返回一个类一个普通的旧POCO类,但在这种情况下,我们已经开始充实业务逻辑,以防止无效状态
对于前端,您可能希望通过JSON将这一切下推到angular或knockout之类的东西,它可以动态呈现可用的选项,并根据组之间的依赖关系显示或隐藏不同的元素
正面工作示例
我不确定您使用的是什么前端绑定,或者您是否只使用razor,在这种情况下,您需要在服务器上存储状态并刷新每个选择,但我在这里提供了一个使用Knockoutjs的示例:使用工作依赖项和动态javascript对象生成器
按组遍历提供的JSON产品
创建根据目标依赖项而变化的计算字段
通过敲除绑定到视图
选定的SKU可以简单地传递给服务器,任何业务规则也可以在前端javascript中实现
当然,从客户端发送到服务器的任何数据都需要通过在服务器上建立产品图并检查所提供的SKU是否有效来验证,即,您不希望为汽油发动机选择柴油涡轮增压器。根据问题的复杂性,您可能会发现域驱动的问题设计有助于将代码拆分为更小、更易于维护的模块,同时提供更深入的见解非常感谢@g18c提供的详细答案。我将详细回顾这一点,并将其标记为答案:@PratikKothari希望这有帮助,如果这能回答您的问题,请将其标记为已回答,如果您还有问题,请告诉我,并乐意回答。你也可以随时打开悬赏来吸引更多的注意力!由于项目的一些要求发生了变化,我仍在研究一些细节。您的回答非常详尽,我感谢您花时间提供JSFIDLE链接。我已将此标记为答案。再次感谢。