【问题标题】:Interfaces for fluent ordered constructor流利有序构造函数的接口
【发布时间】:2013-09-25 07:50:41
【问题描述】:

我正在为流畅的有序构造函数创建一个接口,我已经编写了以下代码:

public interface IMyObjectFactory: IObjectWithProperty
{
  int objectId { get; set; }
  IObjectWithProperty WithObjectId(int id);
}

public interface IObjectWithProperty
{
  IObjectWithProperty WithObjectId(int id);
  MyObject Create();
}

第二个接口需要在构造方法中强制执行顺序

意思是这样的:

public class MyObjectFactory: IMyObjectFactory
{
    public int objectId { get; set; }
    private MyObjectFactory() { }
    public static IObjectWithProperty BeginCreation()
    {
        return new ObjectFactory();
    }
    public IObjectWithProperty WithObjectId(int id)
    {
        objectId = id;
        return this;
    }

    public MyObject Create()
    {
        return new MyObject(this);
    }
}

这是我的目标:

public class MyObject
{
  public int Id { get; set; }
  public MyObject(IMyObjectFactory factory)
  {
    this.Id = factory.objectId;
  }
}

所以我可以写

MyObject mo = MyObjectFactory.BeginCreation().WithObjectId(1).Create();

但是:

  • 我必须在构造函数的接口和实现中定义属性,我不太喜欢
  • 静态 BeginCreation 方法没有接口
  • 我必须公开 impl 属性,而我希望它是内部的
  • 在界面中我收到此警告:Warning 7 'FunzIA.DL.Factory.Interfaces.IMyObjectFactory.WithObjectId(int)' hides inherited member 'FunzIA.DL.Factory.Interfaces.IObjectWithProperty.WithObjectId(int)'. Use the new keyword if hiding was intended.

但这不是一种新方法,我需要第二个接口来强制执行命令

有什么建议吗?谢谢

【问题讨论】:

  • 为什么在WithObjectId 中需要同样的方法?您可以通过继承获得它。
  • 排除这个使用:MyObjectFactory.WithObjectId(1),它强制你必须先调用BeginCreation()

标签: c# interface constructor fluent


【解决方案1】:
public class MyObjectFactory: IMyObjectFactory
{
  private int objectId;
  private MyObjectFactory() { }

  public static IObjectWithProperty BeginCreation()
  {
    return new ObjectFactory();
  }

  public IObjectWithProperty WithObjectId(int id)
  {
    objectId = id;
    return this;
  }

  public MyObject Create()
  {
    return new MyObject(objectId);
  }
}

public class MyObject
{
  public int Id { get; set; }
  public MyObject(int objectId)
  {
    this.Id = objectId;
  }
}

我的看法:

  • 您可以删除WithObjectId 中的IMyObjectFactory。你通过继承得到它。此设置是您收到警告的原因。
  • BeginCreation 很好。在某些时候,您必须创建真实世界的对象,而仅使用接口是不可能的。你需要真正的课程。
  • 我永远不会让MyObject 知道任何工厂。工厂知道并创建对象,而不是相反。 Create 应该构造 MyObject。这也导致不需要拥有 objectId 属性(无论如何您都不喜欢)。

【讨论】:

  • WithObjectId 已移除:我从包含第二个接口的 impl 中提取接口并造成一些混乱
  • 我不想让其他类能够在没有工厂的情况下创建对象,但我喜欢调用对象构造函数的想法:这样调用对象的人看到他必须使用工厂跨度>
  • 其他问题:构造函数使用接口是正确的还是移动与抽象工厂更好?
  • 视情况而定。您可能希望使对象类至少是内部的,具有对象接口。从而使大家通过工厂的流畅界面。如果你需要的话。
  • 不,公共对象没问题,我只想保护创建部分,以便仅使用所有需要的参数创建实例。我只使用 fluent 来避免构造函数带有许多参数(在示例中只有一个,但在实际情况下更多)
【解决方案2】:

我是这样做的:

  • 只是不想让类构造函数可见,我只希望工厂可以访问


public interface IMyObjectFactory: IObjectWithProperty
{
  int objectId { get; set; }
}

public interface IObjectWithProperty
{
  IObjectWithProperty WithObjectId(int id);
  MyObject Create();
}

public class MyObjectFactory: IMyObjectFactory
{
  public int objectId;
  private MyObjectFactory() { }

  public static IObjectWithProperty BeginCreation()
  {
    return new MyObjectFactory();
  }

  public IObjectWithProperty WithObjectId(int id)
  {
    objectId = id;
    return this;
  }

  public MyObject Create()
  {
    return new MyObject(this);
  }
}

public class MyObject
{
  public int Id { get; set; }
  public MyObject(IMyObjectFactory factory)
  {
    this.Id = factory.objectId;
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 2011-02-17
    • 2017-04-10
    • 1970-01-01
    • 2010-12-13
    相关资源
    最近更新 更多