C# class 子工厂 classes
C# class factory with subclasses
我正在努力创建一个工厂模式,其中不是工厂,但 classes 确定需要使用哪个 class 来创建对象。为了使它比普通工厂模式更复杂,classes 通常需要创建一个 subclass 的实例。
我想做类似的事情:
class Observation {
public int NumLegs;
public bool HasWings;
public NumChromosomes;
// etc.
}
class Organism {
public static Organism CreateByObservation(Observation obs) {
if (obs.numLegs == 4) return new Mammal.CreateByObservation(obs);
else if (obs.HasWings) return new Bird.CreateByObservation(obs);
// etc.
}
}
class Mammal: Organism {
public static override Mammal CreateByObservation(Observation obs) {
if (obs.NibblesALot) return new Rodent.CreateByObservation(obs);
else if (obs.Whinnies) return new Horse();
// etc.
}
}
class Rodent: Mammal {
public static override Rodent CreateByObservation(Observation obs) {
if (obs.Color == Colors.GRAY) return new Mouse();
else // ... you get the idea
}
}
// usage:
var myobservation = new Observation() { ... };
var myorganism = new Organism.CreateByObservation(myobservation);
tbName = myorganism.GetName();
出于显而易见的原因,我想将确定代码封装在 subclasses 中(有机体应该对啮齿动物一无所知),但由于在 C# 中不允许覆盖静态方法,我无法使用上面的代码。
处理此问题的最佳方法是什么?
您可以考虑将生物体工厂与生物体数据分开 类。这意味着您将工厂与数据 类 耦合,但不会将数据 类 相互耦合(除了通过继承)。
例如:
//Organism objects
class Organism { ... }
class Mammal : Organism { ... }
class Rodent : Mammal { ... }
//Factory
class OrganismFactory
{
public static Organism CreateByObservation(Observation obs)
{
if (obs.numLegs == 4) return new Mammal.CreateByObservation(obs);
else if (obs.HasWings) return new Bird.CreateByObservation(obs);
// etc.
}
}
如果您的应用程序增长,您可以查看程序集扫描。基本上你可以创建各种实现此接口的 classes,每个可能的 Organism 子类型一个 class
interface IOrganismSubFactory
{
Organism Create(Observation observation);
}
例如一个 "sub" 工厂可能看起来像这样
class MammalFactory : IOrganismSubFactory
{
public Organism Create(Observation observation)
{
if (observation.NumLegs != 4) return null;
return new Mammal(obs);
}
}
现在要将事物联系在一起,您可以扫描程序集并获取所有可能的子工厂并将它们联合到工厂中,就像这样
class OrganismFactory
{
IOrganismSubFactory[] _subFactories;
public OrganismFactory()
{
_subFactories = Assembly.GetCallingAssembly().GetTypes()
.Where(t => typeof(IOrganismSubFactory).IsAssignableFrom(t))
.Select(t => (IOrganismSubFactory)Activator.CreateInstance(t))
.ToArray();
}
public Organism Create(Observation observation)
{
return _subFactories.Select(factory => factory.Create(observation)).FirstOrDefault(instance => instance != null);
}
}
然后您可以使用这个工厂来创建(我们尝试创建)实例
var factory = new OrganismFactory();
var organism = factory.Create(observation);
// organism is null if no factory was found
这可能是个好主意的原因是你的代码是明确分开的,但你必须记住为每个可能的地方创建工厂 class。
另一个优势是您可以使用依赖注入库来包装此逻辑,然后使您能够使用 IoC。基本上这意味着子工厂可以声明对其他 class 的依赖关系,这些 class 会自动注入到这些子工厂中。
这可能超出了您当前问题的范围,但仍然很有趣
我正在努力创建一个工厂模式,其中不是工厂,但 classes 确定需要使用哪个 class 来创建对象。为了使它比普通工厂模式更复杂,classes 通常需要创建一个 subclass 的实例。
我想做类似的事情:
class Observation {
public int NumLegs;
public bool HasWings;
public NumChromosomes;
// etc.
}
class Organism {
public static Organism CreateByObservation(Observation obs) {
if (obs.numLegs == 4) return new Mammal.CreateByObservation(obs);
else if (obs.HasWings) return new Bird.CreateByObservation(obs);
// etc.
}
}
class Mammal: Organism {
public static override Mammal CreateByObservation(Observation obs) {
if (obs.NibblesALot) return new Rodent.CreateByObservation(obs);
else if (obs.Whinnies) return new Horse();
// etc.
}
}
class Rodent: Mammal {
public static override Rodent CreateByObservation(Observation obs) {
if (obs.Color == Colors.GRAY) return new Mouse();
else // ... you get the idea
}
}
// usage:
var myobservation = new Observation() { ... };
var myorganism = new Organism.CreateByObservation(myobservation);
tbName = myorganism.GetName();
出于显而易见的原因,我想将确定代码封装在 subclasses 中(有机体应该对啮齿动物一无所知),但由于在 C# 中不允许覆盖静态方法,我无法使用上面的代码。
处理此问题的最佳方法是什么?
您可以考虑将生物体工厂与生物体数据分开 类。这意味着您将工厂与数据 类 耦合,但不会将数据 类 相互耦合(除了通过继承)。
例如:
//Organism objects
class Organism { ... }
class Mammal : Organism { ... }
class Rodent : Mammal { ... }
//Factory
class OrganismFactory
{
public static Organism CreateByObservation(Observation obs)
{
if (obs.numLegs == 4) return new Mammal.CreateByObservation(obs);
else if (obs.HasWings) return new Bird.CreateByObservation(obs);
// etc.
}
}
如果您的应用程序增长,您可以查看程序集扫描。基本上你可以创建各种实现此接口的 classes,每个可能的 Organism 子类型一个 class
interface IOrganismSubFactory
{
Organism Create(Observation observation);
}
例如一个 "sub" 工厂可能看起来像这样
class MammalFactory : IOrganismSubFactory
{
public Organism Create(Observation observation)
{
if (observation.NumLegs != 4) return null;
return new Mammal(obs);
}
}
现在要将事物联系在一起,您可以扫描程序集并获取所有可能的子工厂并将它们联合到工厂中,就像这样
class OrganismFactory
{
IOrganismSubFactory[] _subFactories;
public OrganismFactory()
{
_subFactories = Assembly.GetCallingAssembly().GetTypes()
.Where(t => typeof(IOrganismSubFactory).IsAssignableFrom(t))
.Select(t => (IOrganismSubFactory)Activator.CreateInstance(t))
.ToArray();
}
public Organism Create(Observation observation)
{
return _subFactories.Select(factory => factory.Create(observation)).FirstOrDefault(instance => instance != null);
}
}
然后您可以使用这个工厂来创建(我们尝试创建)实例
var factory = new OrganismFactory();
var organism = factory.Create(observation);
// organism is null if no factory was found
这可能是个好主意的原因是你的代码是明确分开的,但你必须记住为每个可能的地方创建工厂 class。
另一个优势是您可以使用依赖注入库来包装此逻辑,然后使您能够使用 IoC。基本上这意味着子工厂可以声明对其他 class 的依赖关系,这些 class 会自动注入到这些子工厂中。
这可能超出了您当前问题的范围,但仍然很有趣