我该如何选择AbstractFactory的实例?

时间:2015-05-20 08:18:58

标签: c# architecture code-design abstract-factory

目前我在实例化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?

3 个答案:

答案 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());   
}