【问题标题】:Designing different Factory classes (and what to use as argument to the factories!)设计不同的工厂类(以及使用什么作为工厂的参数!)
【发布时间】:2010-04-12 16:13:31
【问题描述】:

假设我们有以下代码:

public class Event { }

public class SportEvent1 : Event { }
public class SportEvent2 : Event { }

public class MedicalEvent1 : Event { }
public class MedicalEvent2 : Event { }

public interface IEventFactory
{
    bool AcceptsInputString(string inputString);
    Event CreateEvent(string inputString);
}

public class EventFactory
{
    private List<IEventFactory> factories = new List<IEventFactory>();

    public void AddFactory(IEventFactory factory)
    {
        factories.Add(factory);
    }

    //I don't see a point in defining a RemoveFactory() so I won't.

    public Event CreateEvent(string inputString)
    {
        try
        {
            //iterate through all factories. If one and only one of them accepts
            //the string, generate the event. Otherwise, throw an exception.
            return factories.Single(factory => factory.AcceptsInputString(inputString)).CreateEvent(inputString);
        }
        catch (InvalidOperationException e)
        {
            throw new InvalidOperationException("Either there was no valid factory avaliable or there was more than one for the specified kind of Event.", e);
        }
    }
}

public class SportEvent1Factory : IEventFactory
{
    public bool AcceptsInputString(string inputString)
    {
        return inputString.StartsWith("SportEvent1");
    }

    public Event CreateEvent(string inputString)
    {
        return new SportEvent1();
    }
}

public class MedicalEvent1Factory : IEventFactory
{
    public bool AcceptsInputString(string inputString)
    {
        return inputString.StartsWith("MedicalEvent1");
    }

    public Event CreateEvent(string inputString)
    {
        return new MedicalEvent1();
    }
}

下面是运行它的代码:

    static void Main(string[] args)
    {
        EventFactory medicalEventFactory = new EventFactory();
        medicalEventFactory.AddFactory(new MedicalEvent1Factory());
        medicalEventFactory.AddFactory(new MedicalEvent2Factory());

        EventFactory sportsEventFactory = new EventFactory();
        sportsEventFactory.AddFactory(new SportEvent1Factory());
        sportsEventFactory.AddFactory(new SportEvent2Factory());
    }

我有几个问题:

  1. 不必添加工厂 在我的主要方法中 应用程序,我应该尝试 重新设计我的EventFactory 类 是抽象工厂吗?会是 如果我有办法不拥有会更好 手动添加 每次我想要的事件工厂 使用它们。所以我可以实例化 MedicalFactory 和 SportsFactory。我应该建立一个工厂工厂吗?也许这会过度设计?
  2. 您可能已经注意到,我使用inputString 字符串作为参数来为工厂提供数据。我有一个应用程序,它可以让用户创建自己的事件,但也可以从文本文件中加载/保存它们。稍后,我可能想添加其他类型的文件、XML、sql 连接等等。我能想到的唯一能让我完成这项工作的方法是使用内部格式(我选择一个字符串,因为它很容易理解)。你会怎么做这个?我认为这是一个经常发生的情况,可能你们中的大多数人都知道任何其他更聪明的方法。然后我只在EventFactory 中循环其列表中的所有工厂,以检查它们是否接受输入字符串。如果有,那么它会要求它生成Event

如果您发现我用来实现这一点的方法有问题或尴尬,我很高兴听到不同的实现方式。谢谢!

PS:虽然我没有在这里展示,但所有不同类型的事件都有不同的属性,所以我必须使用不同的参数生成它们(SportEvent1 可能有SportNameDuration 属性,必须作为参数放入 inputString 中)。

【问题讨论】:

  • 大多数时候,创建抽象工厂所需的工作都被浪费了,因为 IoC 容器是它们的核心,抽象工厂。看看使用 StructureMap、Windsor、Ninject、AutoFac、Unity、Sprint.NET 或任何其他可用的 IoC 容器。

标签: c# design-patterns oop


【解决方案1】:

我不确定输入字符串的问题,但对于第一个问题,您可能会使用“约定优于配置”;结合反射、IEventFActory 类型和您已有的命名,Name.EndsWith("EventFactory") 应该允许您实例化工厂并使用代码将它们放入它们的列表中。

HTH ,
浆果

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多