- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
任何需要运行时值来构造特定依赖项的地方,抽象工厂都是解决方案。
我的问题是:为什么许多消息来源更喜欢 FactoryInterface 而不是 FactoryDelegate 来实现这种模式?这两种解决方案的优缺点是什么?
下面是一个例子来理解我的意思
如果您有一个服务需要一个具有特定上下文的存储库,那么服务构造函数需要一个工厂来创建或访问其存储库。
常见的解决方案是像这样创建一个RepositoryFactoryInterface。
public IRepositoryFactory {
IRepository Create(ContextInformation context);
}
public class MyService {
private IRepositoryFactory repositoryFactory;
public MyService(IRepositoryFactory repositoryFactory)
{
this.repositoryFactory = repositoryFactory:
}
public void DoSomeService()
{
ContextInformation context = ....;
IRepository repository = this.repositoryFactory.Create(context);
repository.Load(...);
...
repository.Save(...);
}
}
您还需要以某种方式实现 IRepositoryFactory 接口(interface)
public MyEf4RepositoryFactory : IRepositoryFactory
{
IRepository Create(ContextInformation context)
{
return new MyEf4Repository(context);
}
}
...并在应用程序中使用它
public void main()
{
IRepositoryFactory repoFactory = new MyEf4RepositoryFactory();
IService service = new MyService(repoFactory);
service.DoSomeService();
}
----- 主流方案结束------
除了 RepositoryFactoryInterface,您还可以使用 factorydelegate 执行相同的操作,这样需要更少的编码。
public class MyService {
private Func<ContextInformation, IRepository> repositoryFactory;
public MyService(Func<ContextInformation, IRepository> repositoryFactory)
{
this.repositoryFactory = repositoryFactory:
}
public void DoSomeService()
{
ContextInformation context = ....;
IRepository repository = this.repositoryFactory(context);
repository.Load(...);
...
repository.Save(...);
}
}
...并在应用程序中使用它
public void main()
{
IService service = new MyService(context => new MyEf4Repository(context));
service.DoSomeService();
}
在我看来,factorydelegate context => new MyEf4Repository(context)
比声明和实现接口(interface) IRepositoryFactory
和 MyEf4RepositoryFactory
。
这一定是有原因的,我想知道为什么。
这是一个使用接口(interface)方法的示例源:answer to is-there-a-pattern-for-initializing-objects-created-via-a-di-container
[更新]在问了这个问题 15 个月后,有了更多 java universers 的经验,我改变了主意:现在我更喜欢接口(interface)而不是委托(delegate)。但我不能说为什么。这只是一种感觉。也许是因为我更习惯了?
最佳答案
Any place where you need a run-time value to construct a particular dependency, Abstract Factory is the solution.
我会反对这一点。不应使用运行时数据构建依赖关系,如 explained here .总之,文章指出:
Don't inject runtime data into application components during construction; it causes ambiguity, complicates the composition root with an extra responsibility and makes it extraordinarily hard to verify the correctness of your DI configuration. Instead, let runtime data flow through the method calls of constructed object graphs.
当我们改为让运行时数据“流经构造对象图的方法调用”时,您会发现抽象工厂的用处在下降。当使用运行时数据从多个依赖项中进行选择时(与将运行时数据注入(inject)依赖项相比),它们可能仍会被使用,但即便如此,抽象工厂通常也不是最佳解决方案,因为 explained here .总之,文章指出:
Generally, the use of a factory abstraction is not a design that considers its consumers. According to the Dependency Injection Principle (DIP), abstractions should be defined by their clients, and since a factory increases the number of dependencies a client is forced to depend upon, the abstraction is clearly not created in favor of the client and we can therefore consider this to be in violation of the DIP.
相反,Facade、Composite、Mediator 和 Proxy 等模式通常是更好的解决方案。
这并不意味着您的应用程序中不能包含产生依赖关系的代码,但不应将其定义为由其他应用程序组件使用的抽象。相反,应该将类似工厂的行为封装到定义为 Composition Root 的一部分的适配器中。 .
当您只有这些类似工厂的逻辑和依赖项作为组合根的一部分时,是否定义 IRepositoryFactory
并不重要或者仅仅使用 Func<IRepository>
构建这样的依赖关系,因为 IRepositoryFactory
也会在组合根中定义(因为应用程序没有使用此类工厂的业务)。
也就是说,在极少数情况下抽象工厂是正确的抽象(这通常会在构建可重用框架时发生),我确实发现工厂接口(interface)的使用比委托(delegate)的使用更能揭示意图。它有点冗长,但更清楚这样的事情的含义。一个IControllerFactory
比 Func<IController>
更能说明问题.
我会说这更适用于不产生依赖性而是产生数据值的工厂。以注入(inject) Func<DateTime>
为例进入构造函数。这实际上意味着什么,它返回什么值?它返回 DateTime.Now
是否直观? , 还是返回 DateTime.Today
, 或者是其他东西?在那种情况下,定义一个 ITimeProvider
会更清楚。与 GetCurrentTime()
的接口(interface)方法。
注意:此答案于 2017 年 7 月更新以反射(reflect)我的最新观点。
关于c# - IoC 工厂 : Pros and contras for Interface versus Delegates,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5404084/
编写一个仅用于集中其他接口(interface)的接口(interface)是好的做法还是坏的做法? interface InterfaceA : InterfaceB, InterfaceC { }
有没有一种方法可以确定具体类型从任意接口(interface)列表?我知道类型转换,但我想知道所有满意的接口(interface)。 例如,给定: type Mover interface { Mo
我正在尝试制作斐波那契堆。 (在我正在上的算法课中多次提到它们,我想检查一下。)我希望堆使用任何类型的节点,所以我定义了一个 Node 接口(interface): package node type
这是我的代码: type IA interface { FB() IB } type IB interface { Bar() string } type A struct {
示例 A: // pseudo code interface IFoo { void bar(); } class FooPlatformA : IFoo { void bar() {
合并它编译的 leppies 反馈 - 但 IMO 有一些缺点,我希望编译器强制每个子类定义它们自己的 Uri 属性。现在的代码: [] type UriUserControl() = inh
我正在构建一个项目,该项目从用户那里获取一个术语,然后执行谷歌搜索并返回一个 json 格式的标题列表。 我正在使用 serpwow API 来执行谷歌搜索并试图解析响应。 但是我收到的错误是: pa
我只想在其他接口(interface)中实现某些接口(interface),我不希望它们能够被类直接继承。 提前致谢! 最佳答案 您不能在 C# 中执行此操作 - 任何类都可以实现它有权访问的任何接口
我是 Go 的新手,还有一些我还没有掌握的技巧 例如,我有一个可以这样调用的函数: myVar.InitOperation("foo",Operator.EQUAL,"bar") myVar.Init
我有一个通用接口(interface)来描述对输出流的访问,如下所示: interface IOutput { function writeInteger(aValue:Int):Void;
我正在做一个项目,我想通过某种接口(interface)(最好是 USB)将光电探测器电路安装到计算机上。但是,由于我是新手,所以我不知道应该朝哪个方向处理这个问题。假设我有一个带有 USB 连接的光
背景 我正在尝试创建一个简单的应用程序,以真正理解DDD + TDD + etc的整个堆栈。我的目标是在运行时动态注入DAL存储库类。这让我 域和应用程序服务层可测试。我打算用“穷人的DI”来完成 现
在 Java 中,接口(interface)扩展接口(interface)是完全合法的。 UML 中的这种关系看起来像“扩展”关系(实线、闭合、未填充的箭头)还是“实现”关系(虚线、闭合、未填充的箭头
我想创建一个具有相等和比较函数默认实现的接口(interface)。 如果我从类型 IKeyable 中删除所有内容除了Key成员,只要我不添加默认实现,它就是一个有效的接口(interface)。从
COM 中的双接口(interface)是能够通过 DispInterface 或 VTable 方法访问的接口(interface)。 现在有人可以告诉我这两种方法之间到底有什么区别吗? 我认为 V
我有一个类方法,它返回一个可以迭代的员工列表。返回列表的最佳方式是什么?通常我只返回一个 ArrayList。然而,据我了解,界面更适合这种类型的操作。哪个是最好使用的界面?另外,为什么返回接口(in
我想从包装类外部实例化一个内部非静态接口(interface)。 这可能吗? 考虑以下代码: shared class AOuterClass() { Integer val = 3; shared
我为一个类编写了一个接口(interface),如下所示: public interface IGenericMultipleRepository { Lazy> addresses { ge
我是 UML 的初学者,现在我正在创建一个序列图,问题是我想根据用户输入实现 DAO 接口(interface)。如何在时序图中正确绘制以实现接口(interface)。 最佳答案 您不会在 SD 上
要使用 jsr 303 验证创建有条件验证的组,请将接口(interface)类传递给注释,如下所示: @NotEmpty (groups={UpdateValue.class}) 我有很多不同的接口
我是一名优秀的程序员,十分优秀!