【问题标题】:Abstract factory - How to remove the dependency of the concrete factory from the client抽象工厂 - 如何从客户端移除具体工厂的依赖
【发布时间】:2015-09-23 19:05:29
【问题描述】:

在所有抽象工厂实现中,调用代码(客户端)必须知道具体工厂。这只是消除了对产品的依赖,并将这种依赖替换为对具体工厂的依赖。几乎所有的例子都是这样做的。有没有办法从客户端移除这种依赖关系?

【问题讨论】:

  • 继续向上推依赖,直到到达组合根。组合根是唯一应该使用混凝土的地方。

标签: design-patterns solid-principles ooad


【解决方案1】:

您可以通过将工厂作为 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) 
    {
        //... 
    }
}

【讨论】:

    【解决方案2】:

    我在这里没有看到对具体工厂的依赖:

    partial class FactoryClient
    {
        private readonly IThingFactory _thingFactory;
        public FactoryClient(IThingFactory thingFactory)
        {
            _thingFactory = thingFactory;
        }
        public void Work()
        {
            // ...
            var thing = _thingFactory.Create(1, 2, 3);
            // ...
        }
    }
    

    您可以将IThingFactory 的任何自定义实现注入FactoryClientFactoryClient 只依赖于IThingFactory 接口。

    如果你真的想创建对象,你不能避免依赖于你创建对象的方式(参数和其他细节)。您能做的最好的事情 - 在接口中指定此依赖项并在更高级别上找到适当的实现。

    【讨论】:

      【解决方案3】:

      显然是通过创建一个返回工厂的类,也就是工厂工厂。但这只是用对工厂工厂的依赖替换了对工厂的依赖。但是这个问题很容易通过建立一个创建工厂工厂的工厂来解决。等等。

      现在想想你这样做会得到什么。

      【讨论】:

      • 那为什么不让客户依赖它自己的产品呢。无论如何,客户必须依赖某个类(Concretefactory)
      • 那样做。想想你得到了什么。没有?那又怎样,不要那样做还是怎样?
      猜你喜欢
      • 2015-08-06
      • 2015-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      • 1970-01-01
      相关资源
      最近更新 更多