Проектирование различных классов Factory (и что использовать в качестве аргумента для фабрик!) - PullRequest
0 голосов
/ 12 апреля 2010

Допустим, у нас есть следующий фрагмент кода:

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 так что такое абстрактная фабрика? Было бы лучше бы у меня был способ не иметь вручную добавить EventFactories каждый раз, когда я хочу используй их. Так что я могу просто создать экземпляр MedicalFactory и SportsFactory Должен ли я сделать фабрику заводов? Может быть, это было бы чрезмерно инженерно?
  2. Как вы, наверное, заметили, я использую строку inputString в качестве аргумента для подачи на фабрики. У меня есть приложение, которое позволяет пользователю создавать свои собственные события, а также загружать / сохранять их из текстовых файлов. Позже я мог бы хотеть добавить другие виды файлов, XML, соединения SQL, что угодно. Единственный способ, которым я могу думать об этом, позволил бы мне выполнить эту работу - это иметь внутренний формат (я выбираю строку, как это легко понять). Как бы вы сделали это? Я предполагаю, что это повторяющаяся ситуация, вероятно, большинство из вас знают о каком-либо другом более разумном подходе к этому. Тогда я только зацикливаюсь на EventFactory для всех фабрик в его списке, чтобы проверить, принимает ли какая-либо из них входную строку. Если это так, то он просит его сгенерировать Event.

Если вы обнаружите, что в методе, который я использую для этого, что-то не так или неловко, я был бы рад услышать о различных реализациях. Спасибо!

PS: Хотя я не показываю это здесь, все различные виды событий имеют разные свойства, поэтому я должен генерировать их с разными аргументами (SportEvent1 может иметь свойства SportName и Duration, которые должны быть помещен в inputString как аргумент).

1 Ответ

1 голос
/ 13 апреля 2010

Я не уверен насчет вопроса о входной строке, но для первого вопроса вы, вероятно, можете использовать «соглашение о конфигурации»; Name.EndsWith ("EventFactory") должна сочетать рефлексию, тип IEventFActory и имя, которое у вас уже есть, и позволяет создавать экземпляры фабрик и помещать их в списки с помощью кода.

HTH,
Berryl

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...