C# 工厂应该设置模型属性吗?
作为整体编程工作的一部分,我在基本框架API中创建了一个工厂接口&一个抽象工厂 人们已经开始让工厂创建方法负担过重。问题是人们正在用模型属性重载Create方法(从而期望工厂填充它们) 在我看来,属性设置不应由工厂完成。我错了吗?C# 工厂应该设置模型属性吗?,c#,asp.net,solid-principles,C#,Asp.net,Solid Principles,作为整体编程工作的一部分,我在基本框架API中创建了一个工厂接口&一个抽象工厂 人们已经开始让工厂创建方法负担过重。问题是人们正在用模型属性重载Create方法(从而期望工厂填充它们) 在我看来,属性设置不应由工厂完成。我错了吗? public interface IFactory { I Create<C, I>(); I Create<C, I>(long id); //<--- I feel doing this is incorrect
public interface IFactory
{
I Create<C, I>();
I Create<C, I>(long id); //<--- I feel doing this is incorrect
IFactoryTransformer Transformer { get; }
IFactoryDataAccessor DataAccessor { get; }
IFactoryValidator Validator { get; }
}
更新-那我为什么要坚持这种分离呢?我觉得将责任分离有利于更小的对象、更小的单元测试,并提高了可靠性和维护。我知道这样做是以创建更多对象为代价的……但这正是SOLID Factory保护我的……它隐藏了收集和实例化所述对象的复杂性。我认为它是坚持的,只要它是简单的值,我不认为它是问题/冲突。而不是
var model = this.factory.Create();
model.Id = 10;
model.Name = "X20";
分散在您的代码库中,将其放在一个地方几乎总是更好的。未来的合同变更、重构或新需求将更容易处理
值得注意的是,如果这样的对象创建然后立即设置属性是常见的,那么这就是您的团队发展的模式,而开发人员添加重载只是对这一事实的响应(值得注意的是,这是一个好的响应)。引入一个API来简化这个过程是应该做的
再说一次,如果它缩小到简单的赋值(就像在你的例子中),我会毫不犹豫地保留重载,特别是如果你经常注意到它的话。当事情变得更复杂时,这将是新模式被发现的迹象,也许你应该求助于其他标准解决方案(例如)。假设你的工厂接口是从应用程序代码(而不是基础结构组合根)使用的,它实际上代表一个服务定位器,就依赖注入而言,这可以被视为一种反模式。另见 请注意,代码如下所示:
var employee = Factory.Create<ExxonMobilEmployee, IEmployee>();
var employee=Factory.Create();
只是语法糖。它不会消除对具体的ExxonMobileMemployee
实现的依赖
您可能还对Mark Seemann的and(说明此类接口如何违反)和其他出版物感兴趣。在依赖项注入方面积累了大约6个月的经验后,我发现工厂应该设置属性的情况很少:
internal
,并且预期属性仅由工厂设置一次。这通常发生在只有get
ter属性的接口上,这些属性的实现预期将通过工厂创建作为底线,将
public set
ters移出工厂。仅设置标记为internal
的属性,让客户端决定需要设置哪些属性(如果允许)。这将保持你的工厂清洁不需要的功能 这怎么不是建设性的?为什么你觉得工厂这样做是错误的?假设您希望工厂创建一个属性为Y的实例X,但前提是该实例X不存在。如果它已经存在,您可以使用现有实例,该实例可能会缓存在工厂中。这是否有明显的缺点?将id
传递给Create
方法违反了什么坚实的原则?SPR?如果工厂没有填充对象,它会做什么?(除了Gong var foo=new foo()我可能错了,但我不明白你在工厂里做什么?你能更好地定义你试图隐藏的“复杂性”吗?我发现很多开发人员将所有创作模式都归为“工厂模式”分类。听起来你设计了一个抽象工厂,所以消费者对具体类型一无所知(类型为I
),而您团队中的其他人将您的工厂视为建设者或存储库(门面模式)。如果您的意图是让工厂只“新建”一个对象,那么您可能需要更清楚地记录这一点,或者以其他方式向您的团队传达这一点。评论不错,Jimmy!我完全同意将数据访问和模型填充部分委托给另一个对象。我也同意构建器模式可能是实现这一点的另一种方式(我使用我称之为DataAccessor的东西)。我尝试将工厂“掩埋”到“构建器”中,发现它在DataAccesser和工厂之间创建了不必要的依赖关系(为什么不将模型传递到构建器中)。对此有何想法?+1,因为我一直喜欢GetPizza()
Wikipedia上的示例……因为我同意生成器模式是@PrisonerZERO团队的方向。@PrisonerZERO:当然,您可以将模型传递给生成器。但这会创建另一种模式,我相信您的开发人员会很快选择:“从工厂抓取对象并立即传递给生成器”-两步,而不是一步(我相信这就是他们在你们工厂引入过载时所“对抗”的东西——见我的编辑)。此外,工厂是否已经依赖DA组件了?@jimmy_keen混凝土工厂确实了解其他具体情况……但在某个时间点,必须做些什么。这就是混凝土工厂的确切目的(以“新建”给定模型所需的正确实例)。而且……我“感觉”这就是这种逻辑的“最佳位置”。但我也喜欢看到其他人做的事情。注意:当无法创建时,我会使用工厂
var model = this.factory.Create();
model.Id = 10;
model.Name = "X20";
var employee = Factory.Create<ExxonMobilEmployee, IEmployee>();