【发布时间】:2021-07-31 01:05:40
【问题描述】:
我有几个彼此不相关的类。
public class Apple
{
}
public class Giraffe
{
}
我可以为每个工厂创建一个单独的工厂,但我想获得如下结构。
Factory<Apple>.CreateSingle();
我想用上面的代码制作一个苹果。还有下面的代码;
Factory<Giraffe>.CreateCollection(20);
我想养 20 只长颈鹿。
为此,我创建了一个 IFactory 通用接口。
public interface IFactory<out T>
{
T CreateSingle();
IEnumerable<T> CreateCollection(int count);
}
每种类型都有一个工厂;
public class AppleFactory : IFactory<Apple>
{
public Apple CreateSingle() =>
new()
{
//some code
};
public IEnumerable<Apple> CreateCollection(int count)
{
// CreateSingle X count times, add to collection and return
}
}
public class GiraffeFactory: IFactory<Giraffe>
{
public Giraffe CreateSingle() =>
new()
{
//some code
};
public IEnumerable<Giraffe> CreateCollection(int count)
{
// CreateSingle X count times, add to collection and return
}
}
主厂长这样;
public static class Factory<T>
{
private static IFactory<T> GetFactory()
{
if (typeof(T) == typeof(Apple)) return (IFactory<T>) new AppleFactory();
if (typeof(T) == typeof(Giraffe)) return (IFactory<T>) new GiraffeFactory();
return null;
}
public static T CreateSingle() => GetFactory().CreateSingle();
public static IEnumerable<T> CreateCollection(int count) => GetFactory().CreateCollection(count);
}
这里的 if 结构看起来很丑。有没有一种方法可以让我以更清洁的方式做我想做的事情?这些天来,我正在努力学习设计模式,并强迫自己使用设计模式。由于这个原因,代码可能看起来不必要地混乱。这完全是实验性的。
[更新]
实际上,我用苹果和长颈鹿来表示数据库对象(订单、客户等)。在单元测试期间,我有时需要模拟这些对象。出于这个原因,我为每种对象类型编写了一个工厂。后来,我想如果我能把这些工厂聚集在一个工厂里。我还检查了抽象工厂方法,但不太合适。
我对代码做了一些更改。单独生成对象对每个对象都有一个单独的结构(因为它的属性不同)。但是在制作了一个作品之后,制作一个系列对所有人来说都是一样的。为此,我将集合生产方式转移到了总厂。
另外,我使用反射在主工厂内选择合适的工厂进行生产。
再一次,我做这一切只是为了实验目的。我没有得到任何有用的结果。我认为无论如何最好使用单独的工厂。
public static class Factory<T>
{
private static IFactory<T> _factory;
private static IFactory<T> SetFactory()
{
var type = typeof(IFactory<T>);
var desiredFactory = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.First(p => type.IsAssignableFrom(p));
if (_factory == null || desiredFactory != _factory.GetType())
{
_factory=(IFactory<T>)Activator.CreateInstance(desiredFactory);
}
return _factory;
}
public static T CreateSingle() => SetFactory().CreateSingle();
public static IEnumerable<T> CreateEnumerable(int count)
{
// I removed creating collection method from each factory to here
}
【问题讨论】:
-
你为什么想要
Factory of Factories。只要符合factory Interface,您就可以拥有单独的工厂。现在如果要添加新工厂,则需要在此处编写新的 IF 语句,这是不可取的,因为它正在更改现有代码,这违反了Close for changes Open for extension原则。无论如何,您似乎事先知道类型,因此您可以直接致电工厂。 -
看起来大多数这些东西都没有存在的理由。或者,至少你还没有提供一个。具有
createApple()、createGiraffe()等的接口有什么问题? -
实际上我用苹果和长颈鹿来表示数据库对象(订单、客户等)。在单元测试期间,我有时需要模拟这些对象。出于这个原因,我为每种对象类型编写了一个工厂。后来,我想如果我能把这些工厂聚集在一个工厂里。我还检查了抽象工厂方法,但它不太适合。我更新了主帖。非常感谢您的回答。
标签: design-patterns