【问题标题】:Interface that contains a way to create an instance包含创建实例的方法的接口
【发布时间】:2013-06-17 18:34:57
【问题描述】:

我需要一个模式:

我正在使用 C#。

假设有三个演员;吉姆、帕特和莎莉。 Pat 的工作是创建一个接口作为 Jim 和 Sally 之间的合同。 Sally 的工作是创建一个实现接口的类,Jim 的工作是编写一个使用 Sally 对象的类。

Jim 不应该知道 Sally 的具体对象,只知道它实现了公共接口。

Pat 需要在合同中包含一种方法,让 Jim 创建 Sally 的具体对象的实例,但作为接口引用。

无法在接口或抽象类中包含静态方法定义,因此您不能执行以下操作:

public interface IFoo
{
    public static IFoo CreateIFoo();
}

Pat 如何编写合同来保证 Sally 会为 Jim 创建一个方法来创建她的具体对象,该具体对象被引用为接口?

【问题讨论】:

  • 工厂模式在这里可能会有所帮助。要么这样,要么您必须将静态方法移至静态帮助程序类,但这不会以任何方式被合同“强制”。
  • 感谢“相信我”,您指出了我的困境,没有办法将工厂强制作为辅助类中的静态方法。

标签: c# interface design-patterns contract


【解决方案1】:

如果可能,请提供 Sally 的实例:

class Jim 
{
    public Jim(Sally sally){ /* ... */ }
}

但是,如果 Jim 需要知道何时构造 Sally,您可以传入一个委托:

class Jim
{
    private Func<Sally> _createSally.

    public Jim(Func<Sally> createSally)
    {
        _createSally = createSally;
    }

    public void ConsumeSally()
    {
        Sally sally = _createSally();
        /* ... */
    }
}

最简单的用法:

var jim = new Jim( () => new Sally() );

你不需要一个类 (Pat) 来知道如何实例化 sally,除非它真的为你的代码增加了价值。无论哪种方式,您可能都不希望吉姆知道帕特,所以如果需要帕特,这就是您想要的:

var jim = new Jim( () => Pat.GetSally() );

【讨论】:

  • 谢谢安德烈,恐怕我对你的条款有点困惑。假设您的意思是“Jim”是 Jim 编写的类,“Sally”是 Sally 编写的实现 IFoo 的类,那么“Jim”不知道“Sally”类,只知道接口 IFoo。而“Jim”不能直接创建“Sally”。此外,如果您的意思是“Pat”是接口 IFoo,则不能实例化“Pat”来调用 GetSally()。没有“Pat”类。
  • 我的意思是一个类不应该知道如何构建它的依赖,这包括不知道工厂(Pat 的类)。如果 Jim(使用依赖项的类)知道 Pat 的(工厂),那么您将拥有一个 Service Locator,它被认为是一种反模式。
  • 如果一个类确实需要知道何时构建它的依赖项(尽管这并不常见),请将其包装在委托或 Lazy 中(仅限 C# 4+)。
  • 我稍后会尝试改进我的答案,现在没有时间。对不起。
【解决方案2】:

听起来你需要一个抽象工厂。除了IFoo,使用CreateFoo方法创建一个接口IFooFactory。给 Jim 一个实现 IFooFactory 的对象实例,Jim 将调用 CreateFoo 方法。创建实现 IFooFactory 的对象实例可能是 Sally 或 Pat 的工作。

【讨论】:

  • 谢谢迈克尔,据我所知,会有一个额外的接口,例如: public interface IFooFactory { public IFoo CreateFoo(); } 这不是把问题推给工厂吗? Jim 如何获得 Sally 创建的 IFooFactory 的具体对象?
  • @dtaylor Sally 有 someFooFactory - 实现IFooFactory 的工厂,它受合同约束以创建IFoo 接口。您可以就地创建工厂或注入具体工厂,这里的要点是:如果 Jim 想要 Sally 的 IFoo,他可以通过调用 IFooFactory.Create() 来获得。
猜你喜欢
  • 2012-01-19
  • 2017-04-26
  • 1970-01-01
  • 2013-02-17
  • 1970-01-01
  • 2011-10-30
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多