C#工厂 - 是必须的?

时间:2011-02-02 08:41:50

标签: c# casting factory factory-pattern

C#工厂模式是否需要向上播放?

我希望上课在图书馆G中在班级图书馆A中创造一个亚当而不使G依赖于A.上帝在班级图书馆E中生产亚当斯以供夏娃消费,并且夏娃可以知道并依赖亚当。 (编辑 - 这个样本越来越好了:)

我能想到的解决方案是在A中有一个AdamFactory。这样AdamFactory知道Adam并且可以很容易地创建它(可能只是调用Adam的构造函数)。上帝收到了一个AdamFactory,可以将它命令为CreateAdam。

现在,因为上帝不被允许认识亚当,AdamFacotry的CreateAdam必须返回一个对象,这需要Eve将AdamFactory返回的对象上传给Adam。

我认为这会奏效。然而,我对上传感到不安,因为这是禁忌。这真的是必须的吗?

P.S。 - 没有Blasphemy的意图,如果某人的感受受到伤害我会道歉。使用上帝和亚当而不是创造者和创造似乎更好,因为后两个词彼此太相似了。

编辑:重新接口建议。让我们假设Adam有两种方法:ProvideLove,ProvideFood和ProvideProtection(我们保持这个样本是kis-safe :)。夏娃将亚当用于这两个目的,但当然上帝没有。那么为什么要向上帝提供AdamFactor返回实现IAdam而不仅仅是对象的东西的知识呢?我不明白!

编辑:工作代码(同一个库中的每个人,我的目标是分隔到不同的库)看起来像这样:

Adam God.LoadAdam(AdamID theAdamID)
       var adam = new Adam(theAdamId, this)

Adam.Adam(AdamID theAdamID, God theGod)
      _god = theGod
      _mind  = theGod.LoadMind(theAdamId, this)

Mind God.LoadMind (AdamID theAdamID, Adam theAdam)
      var mind  = new Mind (theAdam)
      var mindId = new minId(theAdamId)
      mind.DeserializeFromFile(minId)

Mind.Mind (Adam theAdam)
      _adam = theAdam

6 个答案:

答案 0 :(得分:9)

我不确定我是否完全理解这些要求,但这是一个建议:


//in assembly G
public abstract class HumanFactory<T>
{
    public abstract T CreateHuman();
}

//in assembly A
public class Adam { }
//in assembly A
public class AdamFactory : HumanFactory<Adam>
{
    public override Adam CreateHuman()
    {
        return new Adam();
    }
}

//in assembly G
public class God
{
    public T Create<T>(HumanFactory<T> factory)
    {
        return factory.CreateHuman();
    }
}

和用法:


//Somewhere in assembly E
Adam adam = new God().Create(new AdamFactory());

答案 1 :(得分:1)

如何使用界面让上帝知道IAdam,或者像IHuman这样的东西?

答案 2 :(得分:1)

我认为你可以使用依赖注入。尝试使用控制反转(IoC)容器,如Unity 2StructureMapCastle of Windsor

答案 3 :(得分:0)

你正在描述abstract factory pattern,虽然“子”工厂(例如AdamFactory)通常有一些共同点,所以你希望它们能够产生更像公共界面而不仅仅是一个对象的东西(见达维德的答案)

你担心升级是正确的,因为这会将夏娃与亚当的实施联系起来,这会破坏工厂的目的(​​除非你真的把它当作建造者)。

问题是,为什么你需要上帝班?

答案 4 :(得分:0)

好吧,如果上帝是你在评论中提到的持久性类库,那么它不应该影响系统其余部分的类设计。

所以,我不会添加不必要的接口。可以从反序列化器中返回一个对象,然后向下传播(例如BinaryFormatter,XmlSerializer)。

更好的方法是使您的反序列化器具有通用性。

答案 5 :(得分:0)

好的,在这里撒一些仿制品怎么样?

让我们说上帝可以接受符合以下界面的任何类型的工厂:

interface IFactory  {
  Type CreatedType { get; }
  object Create();
}

实现它的抽象类可能如下所示:

abstract class AbstractFactory<T> : IFactory {
  public Type CreatedType { get { return typeof(T); }
  public virtual object Create() {
    return innerCreate();
  }
  protected abstract override T innerCreate();
}

现在,您可以向上帝注册工厂:

God.RegisterFactory(new AdamFactory());

AdamFactory继承自AbstractFactory<Adam>

上帝将其工厂存储在字典中,其中键是IFactory接口返回的类型

现在,Create Method看起来像这样:

God.Create<Adam>();

上帝查看它的工厂,看到有一个用于泛型方法的typeof(T),检索工厂,调用create和downcast到T。

您怎么看?