目前我在实例化AbstractFactory方面遇到了麻烦 有一些课程:
abstract class ABase { }
class A1 : ABase { }
class A2 : ABase { }
abstract class BBase { }
class B1 : BBase
{
private readonly A1 _a;
public B1(A1 a)
{
_a = a;
}
}
class B2 : BBase
{
private readonly A2 _a;
public B2(A2 a)
{
_a = a;
}
}
abstract class FactoryBBase
{
abstract public BBase Create(ABase b);
}
class FactoryB1 : FactoryBBase
{
override public BBase Create(ABase b)
{
return new B1(b as A1);
}
}
class FactoryB2 : FactoryBBase
{
override public BBase Create(ABase b)
{
return new B2(b as A2);
}
}
class Runtime
{
public void ProcessA(ABase a)
{
//How should I choose a proper factory?
}
}
问题是,如何根据ProcessA
的类型在a
方法中实例化适当的抽象工厂?问题是我不想要一个大的if / else块
另一个问题是,我是否应该使用AbstractFactory模式,因为它应该是uesd?
答案 0 :(得分:1)
如何根据?
的类型在ProcessA方法中实例化一个正确的抽象工厂
为了避免使用大的if / else块,可以将所有工厂放入映射中,其中key是a
的类型,value是实现。在Java中我会通过Spring执行此操作,或者我将创建一个静态代码,可以在加载类时初始化地图。
我是否应该使用AbstractFactory模式,因为它应该是uesd?
恕我直言。
答案 1 :(得分:1)
如何实现抽象工厂实际上取决于您的需求。你所拥有的确实是一个正确的实现,但我认为这并不完全是你需要的,因为你想要做一些不同的事情,取决于ABase
实例的类型或状态。
分析类型或状态的逻辑正是我投入工厂的原因。
abstract class ABase { }
class A1 : ABase { }
class A2 : ABase { }
public abstract class FactoryBBase
{
public abstract IProcessor Create(ABase a);
}
public class ConcreteFactory : FactoryBBase
{
override public IProcessor Create(ABase a)
{
// this is ugly for a large amount of ABase implementations of course
if (a is A1)
{
return new Runtime1();
}
if (a is A2)
{
return new Runtime2();
}
throw new NotSupportedException();
}
}
public interface IProcessor
{
void ProcessA(ABase a);
}
public class Runtime1 : IProcessor
{
public void ProcessA(ABase a)
{
// process away
}
}
public class Runtime2 : IProcessor
{
public void ProcessA(ABase a)
{
// process away differently
}
}
当您希望相同类型的ABase
实施由不同类型的运行时/处理器处理时,多个工厂实施会发挥作用,具体取决于状态在ABase
之外。
答案 2 :(得分:1)
您可以使用查找字典而不是if-else / switch结构。
//classes used as markers
public interface IMarker {}
public class MarkerA : IMarker {}
public class MarkerB : IMarker {}
//classes to be created
public interface IData {}
public class DataA : IData {}
public class DataB : IData {}
//factory to call abstract factories (could use static here)
public class Factory
{
public IData Create(IMarker marker)
{
//lookup dictionary instead of if/switch
//func ensures instance is only created when required
var lookup = new Dictionary<Type, Func<DataFactoryBase>>()
{
{ typeof(MarkerA), () => new DataAFactory() },
{ typeof(MarkerB), () => new DataBFactory() },
};
//get factory by type and call constructor
return lookup[marker.GetType()]().Create();
}
}
//abstract factories
public abstract class DataFactoryBase
{
public abstract IData Create();
}
public class DataAFactory : DataFactoryBase
{
public override IData Create()
{
return new DataA();
}
}
public class DataBFactory : DataFactoryBase
{
public override IData Create()
{
return new DataB();
}
}
public static void Main()
{
//example will return DataA
IData data = new Factory().Create(new MarkerA());
}