虽然我应该通过尼尼特或类似的项目使用依赖注入,但我一直试图实现一个抽象工厂设计,它将为我提供以下易于阅读和使用的语法:
UniversalFactory.Factory<IFoo>.Create<FooImpl>(... parameters ...);我把这个实验放在这里是为了征求一些建设性的反馈,包括实现逻辑和设计推理。
以下是我目前的实现:
public class UniversalFactory
{
private readonly IFactory<IFoo> FooFactoryEx;
public UniversalFactory()
{
FooFactoryEx = new FooFactory();
}
public IFactory<T> Factory<T>()
{
if (typeof (T) == typeof (IFoo))
return (IFactory<T>)FooFactoryEx;
return null;
}
}
public interface IFactory<in TF>
{
T Create<T>(params object[] p) where T : TF;
}
public class FooFactory : IFactory<IFoo>
{
public T Create<T>(params object[] p) where T : IFoo
{
if (typeof(T) == typeof(FooImpl))
{
var id = Convert.ToInt32(p[0]);
return (T)FooImpl.Create(id);
}
return default(T);
}
}
public interface IFoo
{
// Some interface
}
public class FooImpl : IFoo
{
public int Id { get; set; }
private FooImpl(int id)
{
Id = id;
}
public static IFoo Create(int id)
{
var foo = new FooImpl(id);
return foo;
}
}此代码允许实例化UniversalFactory并成功调用以下内容:
UniversalFactory.Factory<IFoo>().Create<FooImpl>(1);我对这一做法的推理是:
我目前的实现(至少)存在以下缺陷:
有什么想法?反馈?这种方法是不必要的还是过于复杂的?希望这个实验至少能引起一些其他人的兴趣。
发布于 2014-02-06 05:42:14
严格地说,你要做的不是抽象的工厂。对于抽象工厂,用例应该如下所示:
UniversalFactory.Factory<IFoo> // client has no idea about IFactory<IFoo> implementation
.Create(... parameters ...); // client has no idea about IFoo implementation, returns IFoo理想情况下,您甚至不需要传递参数。这就是你毕竟在建厂的原因。若要委派对象创建,请执行以下操作。
其他次要评论:
where T : TF --这些不是泛型参数的描述性名称。也许你能想出更好的名字。var id = Convert.ToInt32(p[0]); -我不确定我喜欢这里的Convert。它可能会隐藏错误和误用。我认为在这种情况下,坚强的演员会更好。public static IFoo Create(int id) -我不认为有任何理由使用工厂方法。公共类FooImpl : IFoo { public int { get;私有集;} public FooImpl(int id) { Id = id;}这看起来要干净得多。另外,我认为Id策划人应该永远是私密的。总的来说,我认为除非您是出于学习目的,否则您应该只获取一个现有的DI库,就像您自己已经讨论过的那样:)
发布于 2014-02-06 09:40:41
代码编写得很好,但给出一个类是很有力量的。它在本质上造成了依赖瓶颈。
工厂的大部分优点是能够交换/更改/更新实现,而不需要额外的重新编译或更改。
尽管在这里,您正在调用Universal (如果不重新编译使用它的每个类,它作为实现是无法更改的)
其次,在调用本身中调用直接实现。这意味着你也依赖于这一点。
您正确地断言正确的方法可能是DI系统。或者,你可以留在工厂里,做一些类似的事情。
IGlobalFactory factory;//Possibly constructor initialized
IFoo bar = factory.Create<IFoo>();通过该方法注入GlobalFactoryImpl并向工厂提供IFoo的实现。
让您的主类知道存在一个FooImpl通常是个坏主意,这样,GlobalFactoryImpl可以在调用时返回FooImpl,但是GlobalFooBlargFactoryImpl可以返回FooBlargImpl,您仍然可以交换实现,但是一切都有点模糊。
https://codereview.stackexchange.com/questions/41030
复制相似问题