【发布时间】:2015-09-23 19:05:29
【问题描述】:
在所有抽象工厂实现中,调用代码(客户端)必须知道具体工厂。这只是消除了对产品的依赖,并将这种依赖替换为对具体工厂的依赖。几乎所有的例子都是这样做的。有没有办法从客户端移除这种依赖关系?
【问题讨论】:
-
继续向上推依赖,直到到达组合根。组合根是唯一应该使用混凝土的地方。
标签: design-patterns solid-principles ooad
在所有抽象工厂实现中,调用代码(客户端)必须知道具体工厂。这只是消除了对产品的依赖,并将这种依赖替换为对具体工厂的依赖。几乎所有的例子都是这样做的。有没有办法从客户端移除这种依赖关系?
【问题讨论】:
标签: design-patterns solid-principles ooad
您可以通过将工厂作为 lambda 注入来移除任何硬依赖:
static void Main(string[] args)
{
var client = new Client(name => new Service(name));
}
public sealed class Client
{
private readonly IService service;
public Client(Func<string, IService> serviceFactory)
{
this.service = serviceFactory("Client");
}
}
public sealed class Service : IService
{
public Service(string name)
{
//...
}
}
【讨论】:
我在这里没有看到对具体工厂的依赖:
partial class FactoryClient
{
private readonly IThingFactory _thingFactory;
public FactoryClient(IThingFactory thingFactory)
{
_thingFactory = thingFactory;
}
public void Work()
{
// ...
var thing = _thingFactory.Create(1, 2, 3);
// ...
}
}
您可以将IThingFactory 的任何自定义实现注入FactoryClient。 FactoryClient 只依赖于IThingFactory 接口。
如果你真的想创建对象,你不能避免依赖于你创建对象的方式(参数和其他细节)。您能做的最好的事情 - 在接口中指定此依赖项并在更高级别上找到适当的实现。
【讨论】:
显然是通过创建一个返回工厂的类,也就是工厂工厂。但这只是用对工厂工厂的依赖替换了对工厂的依赖。但是这个问题很容易通过建立一个创建工厂工厂的工厂来解决。等等。
现在想想你这样做会得到什么。
【讨论】: