Ghi*_*nio 5 .net c# architecture design-patterns factory-pattern
我有一个工厂类和CreateInstance方法
CreateInstance(EntityModel.TipoEntitaTipoParametroEntita tipoParametroEntita, IParametroEntitaMultiValoreDataSourceProvider parametroEntitaMultiValoreDataSourceProvider)
Run Code Online (Sandbox Code Playgroud)
工厂可以根据值来实例化两个不同的子类型 tipoParametroEntita.TipoCampo.IdTipoCampo
要点是CreateInstance(parametroEntitaMultiValoreDataSourceProvider)的第二个参数仅用于创建实例,TipoEntitaTipoParametroEntitaMultiValore
而不用于创建实例TipoEntitaTipoParametroEntitaSingoloValore
public class TipoEntitaTipoParametroEntitaFactory : ITipoEntitaTipoParametroEntitaFactory
{
/// <summary>
/// Creates an instance of TipoEntitaTipoParametroEntitaSingoloValore or TipoEntitaTipoParametroEntitaMultiValore
/// </summary>
public TipoEntitaTipoParametroEntita CreateInstance(EntityModel.TipoEntitaTipoParametroEntita tipoParametroEntita, IParametroEntitaMultiValoreDataSourceProvider parametroEntitaMultiValoreDataSourceProvider)
{
if (tipoParametroEntita.TipoCampo.IdTipoCampo == (int)EntityModel.Enum.TipoCampo.CampoLibero ||
tipoParametroEntita.TipoCampo.IdTipoCampo == (int)EntityModel.Enum.TipoCampo.CampoLiberoMultiLinea)
{
return new TipoEntitaTipoParametroEntitaSingoloValore(tipoParametroEntita);
}
if (tipoParametroEntita.TipoCampo.IdTipoCampo ==
(int)EntityModel.Enum.TipoCampo.DropdownListQueryDataSource ||
tipoParametroEntita.TipoCampo.IdTipoCampo ==
(int)EntityModel.Enum.TipoCampo.DropdownListTableDataSource)
{
return new TipoEntitaTipoParametroEntitaMultiValore(tipoParametroEntita,
parametroEntitaMultiValoreDataSourceProvider);
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我对这种采用的模式表示怀疑,因为我总是需要传递一个实例,IParametroEntitaMultiValoreDataSourceProvider即使它不是必需的,而且读取方法签名的人可能会认为创建任何类型TipoEntitaTipoParametroEntita的实例IParametroEntitaMultiValoreDataSourceProvider都是必需的.
什么是更好的方法?两个不同的工厂?只有一个工厂和两个CreateInstance(一个返回TipoEntitaTipoParametroEntitaSingoloValore,另一个TipoEntitaTipoParametroEntitaMultiValore)?
我在两种情况下都应该知道哪个工厂或哪个CreateInstance要调用,所以我应该tipoParametroEntita.TipoCampo.IdTipoCampo每次都提前检查.但是我想把这个逻辑保留在一个地方.
小智 2
从函数式编程的角度来看,我在处理所谓的“代数数据类型”(即不同的子类型)时通常会查看访问者模式。无论如何,我并不总是喜欢这种方法,因为一开始可能会很困难。
因此我只会给出基本的想法,以便您可以快速决定是否感兴趣。另请注意,这里的目标是编写带有函数签名的代码,以便可以在编译时发现错误,这与运行时相反。
现在,简而言之,实现此目的的经典方法是利用 C# 语言类型检查功能来定义一个新访问者,其中包括您的CreateInstance签名的所有不同覆盖:
public IEntitaTipoParametroEntita CreateInstance(SubType1 subType1)
{
// ...
}
public IEntitaTipoParametroEntita CreateInstance(SubType2 subType2)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
其中每个子类型应该有自己的
IEntitaTipoParametroEntita accept(CreateVisitor visitor)
{
visitor.CreateInstance(this);
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以避免if类似switch的容易出错的子类型检查语法,而只需实例化特定访问者并将其传递给任何要处理的子类型。
如果子类型之间存在显着的共性,那么将子类型拆分为单独的物理表可能没有什么价值。
因此,就数据库设计而言,“每个层次结构一个表”(它利用类型鉴别器列来保存类型信息)似乎更适合您的示例:它通过反规范化 SQL 模式来实现多态性。要指示实体框架使用此策略,所需要做的就是从DbContext类派生一个类,并为超类型添加DBSet属性,而不DBSet为子类型添加属性。
| 归档时间: |
|
| 查看次数: |
430 次 |
| 最近记录: |