Фабрика Дизайн Шаблон Расширить - PullRequest
1 голос
/ 02 июня 2011

Я читаю Head First Design Pattern и в главе Фабрики.Я думаю изменить один мой рабочий код для его реализации.

Сначала я создаю IAction и ActionFactory с GetAction, из IAction я создаю UploadDatabase, CopyFile, UploadSharepoint и т. Д. Это в DLL и может быть вызвано из exe.Это легко и просто.

Затем я планирую создать AutoCADAction из IAction, который включает такие действия, как «Печать», «Сценарий» и т. Д. Эти действия можно выполнять только в AutoCAD.

Теперь мне нравится создавать AutoCADActionFactory с переопределением GetAction, он будет создавать как ActionFactory, так и AutoCADAction.Теперь я проиграл.

Вот пример кода:

В ActionFactory.GetAction

public IAction GetAction(ActionType myActionType)
{
    switch (myActionType)
    {
        case ActionType.UploadDatabase:
            return new UploadDatabase();

        case ActionType.CopyFile:
            return new CopyFile();

        case ActionType.UploadSharepoint:
            return new UploadSharepoint();
    }
}

Как я кодирую свой AutoCADActionFactory.GetAction, это правильно?

public AutoCADAction GetAction(ActionType myActionType)
{
    return Base.GetAction;
    switch (myActionType)
    {
        case ActionType.Print:
            return new Print();

        case ActionType.Script:
            return new Script();

        ...

    }
}

Спасибо,

1 Ответ

2 голосов
/ 02 июня 2011

Я не совсем уверен, что Фабрика, или, точнее, Фабрика Метод (как вы, похоже, пытаетесь его использовать) является правильным выбором здесь.Причина, по которой я говорю, что вы, кажется, упустили из виду некоторые вещи.

Как правило, фабричный метод имеет больше смысла, когда вы будете выполнять операции, которые делают подобные вещи - например, чтение растрового изображения из файла вразличные форматы.Определенные вами действия, кажется, сильно различаются, и я не уверен, что они должны представлять один и тот же тип операции (т.е. поддерживать один и тот же интерфейс).Конечно, нет причин, по которым ваши действия не должны поддерживать несколько интерфейсов (например, класс Print может реализовывать как IAction , так и IPrint ), но без дополнительныхинформация, я действительно задаюсь вопросом, является ли базовый дизайн настолько твердым, как и должно быть.

Поскольку вы используете одно и то же перечисление ActionType в ActionFactory и AutoCADActionFactory, вы, вероятно, хотите / должны определить «нулевое» действие, котороевозвращается ActionFactory.(В зависимости от контекста, вы можете захотеть, чтобы это нулевое действие выполняло что-то полезное - например, всплывающее окно с сообщением «Эта операция не поддерживается в этом контексте», но оно могло бы с такой же легкостью ничего не делать).должен быть возвращен в случае «По умолчанию».

В том виде, в котором он в данный момент закодирован, вы всегда вернете действие из базового класса.Вы, вероятно, хотите что-то, похожее на это:

public AutoCADAction GetAction(ActionType myActionType)
{
    switch (myActionType)
    {
        case ActionType.Print:
            return new Print();

        case ActionType.Script:
            return new Script();

        default:
            return base.GetAction(myActionType);
    }
}

Это позволит вам полностью заменить действие, предоставляемое ActionFactory (которое, я думаю, было бы наиболее вероятным), или выполнять специализированноетакие вещи, как возврат специализированного действия, которое выполняет некоторую конкретную операцию в дополнение к действию из базового класса.

Возможно, вы также захотите рассмотреть общий объектно-ориентированный принцип «Favor Encapsulation over Inheritance».В этом случае я не вижу реальной выгоды в наследовании от ActionFactory.В случае класса Abstract Factory , где существуют отдельные вызовы для каждого типа действия, наследование обеспечивает большую выгоду.

Помогает ли что-нибудь из этого?

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