jac*_*jac 4 c# design-patterns
我有一个应用程序,多个商店将共享数据.有一个Options表定义了各种程序选项.我有一个varchar列,它定义了值类型,int,bool,Guid,string等.有两个表定义选项值,一个用于系统范围的选项,另一个用于本地选项.基本选项表定义是否可以在系统范围选项之前选择本地选项.Shop和Global选项表基本上是相同的结构,除了ShopOption表具有记录所属商店的ShopId FK.这些表中的每一个都将选项值存储为varchar,尽管该字符串可能表示整数,Guid,bool,或者实际上可能是字符串.我需要显示一个带有本地选项选项卡的表单,一个全局选项选项卡,以及一个用于指定商店是否可以覆盖全局的选项卡.我做得不对的是获得一个选项实体并获得它应该是的类型的值.
例如:
GetOption(SessionTimeout)应该返回一个Option实体,值应该是整数类型.
GetOption(DefaultCustomer)应该返回一个Option实体,值应该是Guid类型.
我正在寻找使用设计模式的答案,并认为工厂模式可能是我想要的,但我只是没有得到它.
根本的问题是,你从苦难内平台作用,因此你正试图使通过存储的数据库中的数据库varchar有什么应该是不同的,类型化的列.
您已经给自己在运行时添加选项的能力.但是,如果应用程序不理解它们,它们就没有任何意义,并且您无法在运行时添加该理解.必须在设计时知道这组选项,这意味着可以在设计时知道模式,这意味着您无需将结构抽象为varchar值.
创建一个包含代表每个选项的列的表,并使用常规ORM实践来声明它映射到的数据类型.
抽象实际上并没有为你买任何东西.
编辑以回应OP的评论:
要实现级联设置,您可以创建一个OptionSet包含每个选项列的表.只有一行代表全局集.对于可由管理器覆盖的每个选项,请向Store表中添加可为空的列.
然后,您可以使用一种方法来要求Store合并有效选项:
public class Store
{
public virtual bool? AllowSavePasswords { get; set; }
public virtual OptionSet GetEffectiveOptions(OptionSet globalOptions)
{
return new OptionSet
{
AllowSavePasswords = this.AllowSavePasswords ?? globalOptions.AllowSavePasswords,
LoginTimeout = globalOptions.LoginTimeout
// Repeat pattern for all options
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这允许所有内容保持强类型,同时解决无法覆盖的选项问题.它还表示该选项的意图可以通过指定所有的人都在覆盖Store表(反映其范围),使他们可以为空(反映其可选性质).
好的部分是没有新技术可供学习或"魔术"实现(除非你没有看到??运算符,这相当于T-SQL的COALESCE功能).