Шаблон проектирования Factory с использованием перечислений и наследования

У меня концептуальная проблема. Я хотел бы использовать фабрику шаблонов проектирования, используя перечисление, чтобы узнать, какой тип объекта создать. Но когда дело доходит до наследования в другой сборке, я придерживаюсь своего перечисления...

Поясню случай:

Я создаю Framework для нескольких проектов, которые управляют фруктами.

Я создаю интерфейс IFruit, реализованный абстрактным классом Fruit, от которого будут наследоваться Strawberry, Apple и Pear.

Я создаю перечисление FruitTypes, которое содержит Strawberry, Apple и Pear.

Я создаю FruitFactory с помощью виртуального метода: GiveMeANewFruit(FruitTypes newFruit), который возвращает IFruit.

Все хорошо.

Я отправляю свой Framework по всему миру, и кому-то на нашем испанском заводе нужно также управлять бананами.

Он создаст класс Banana, который наследует Fruit.

Он создаст SpanishFruitFactory, который будет наследоваться от FruitFactory, и переопределит виртуальный метод GiveMeANewFruit, вот код, который может быть в этом методе:

Public Override IFruit GiveMeANewFruit(FruitTypes newFruit)
{
    if (newFruit == FruitTypes.Banana)
        return new Banana();
    else
        return base.GiveMeANewFruit(newFruit);
}

Но эй, вот проблема. Я знаю, что такие языки, как C#, не позволяют наследовать перечисления. Итак, мой парень не может добавить значение Banana к перечислению FruitTypes.

Итак, каким шаблоном лучше всего заменить перечисление, чтобы я мог дать внешнему миру возможность добавлять новые типы объектов в мою концепцию?

Зная, что я НЕ хочу иметь что-либо вне исходного кода (ни XML-файл, ни базу данных, ни что-либо еще, предоставляющее список типов).

Есть ли у вас какие-либо рекомендации ?


person Sierramike    schedule 27.03.2014    source источник
comment
Это не java, а использование MEF.   -  person clcto    schedule 27.03.2014
comment
Вот введение в MEF: channel9 .msdn.com/Блоги/kreekman/   -  person clcto    schedule 27.03.2014
comment
@clcto Простое указание использовать MEF без каких-либо указаний на то, что вы имеете в виду или как это может быть актуально, не совсем полезно. Я действительно не уверен, какое отношение к этому имеет Фонд горы Эверест.   -  person Chris    schedule 27.03.2014
comment
Вы смотрели на это: stackoverflow.com/a/757815/1693085 - или stackoverflow.com/a/4042826/1693085 - Могут ли они это сделать ??   -  person John Bustos    schedule 27.03.2014
comment
@Sierramike Я бы использовал вторую ссылку в комментарии Джона Бустоса   -  person Pacane    schedule 27.03.2014
comment
@clcto: OMG, я знаю MEF, но это несколько излишне для того, чего я хочу достичь. Кроме того, их структура файлов и каталогов, наложенная для работы MEF, делает его недружественным, я хочу, чтобы он был простым в использовании для других разработчиков. Спасибо, в любом случае.   -  person Sierramike    schedule 28.03.2014
comment
@John Bustos: Я думаю, что ваша вторая ссылка, как говорит Пакан, самая полезная, я бы хотел, чтобы вы поместили ее в качестве ответа, чтобы я мог отметить ее принятой! Спасибо !   -  person Sierramike    schedule 28.03.2014
comment
Как я уже упоминал в комментариях, кажется, что на лучшее решение этой проблемы уже очень хорошо ответили в этой ссылке. Рад, что это сработало для вас!   -  person John Bustos    schedule 28.03.2014
comment
Я только что разместил это как решение, но хотелось бы, чтобы оригинальный постер имел ... Его решение написано лучше, чем я когда-либо мог :p В любом случае, рад, что оно дало вам то, что вы ищете !!   -  person John Bustos    schedule 28.03.2014


Ответы (2)


Я думаю, что лучшая замена static class. Именно так я делаю это в php. Определите static class с полями вместо enum, вы даже можете определить поля как string, если хотите.

person Elvedin Hamzagic    schedule 27.03.2014

Измените фабричный метод, чтобы он принимал int, и реализуйте перечисления, используя такие классы:

public class FruitTypes
{
    public const int Strawberry = 1;
    public const int Apple = 2;
    public const int Pear = 3;
}

public class SpanishFruitTypes : FruitTypes
{
    public const int Banana = 4;
}

Пример использования: -

factory.GiveMeANewFruit(FruitTypes.Pear)

factory.GiveMeANewFruit(SpanishFruitTypes.Banana)
person Andrew Stephens    schedule 27.03.2014