Существуют ли стандартные соглашения об именах для этого примера шаблона метода шаблона? - PullRequest
2 голосов
/ 25 января 2011

Я хочу создать абстрактный класс с общим шаблоном обработки исключений:

public abstract class Widget
{
    public IFoo CreateFoo()
    {
        try
        {
            CreateFooUnsafe();
        }
        catch(Exception ex)
        {
            throw new WidgetException(ex, moreData, evenMoar);
        }
    }

    protected abstract IFoo CreateFooUnsafe();
}

Цель состоит в том, чтобы иметь стандартный шаблон обработки исключений для всех производных объектов.Не следует ожидать, что абстрактный метод CreateFooUnsafe() будет содержать обработку исключений.Реализации, вероятно, будут одной строкой return new Foo(...)

. Что я хочу знать, так это то, существуют ли какие-либо стандартные соглашения об именах, связанные с этим шаблоном, особенно там, где ожидается код, генерирующий исключения?

Названия выше кажутся несколько уместными, но не совсем без запаха .

Ответы [ 3 ]

4 голосов
/ 25 января 2011

Это пример шаблона шаблона .

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

В вашем примере вы используете метод шаблона, чтобы перехватить все исключения, всплывающие из внутренней реализации, и обернуть их в пользовательский тип исключения. Один комментарий, который я хотел бы сделать по поводу этой конкретной практики, заключается в том, что имеет смысл, только если вы можете добавить контекстную информацию, которая позволила бы вызывающему коду лучше обрабатывать исключение . В противном случае может быть лучше просто разрешить распространению исключений источника.

1 голос
/ 23 мая 2012

Короткий ответ - нет.

В шаблоне шаблона нет соглашения о том, какой тип и когда вызывать исключение.Такая информация включена в некоторый раздел документации в соответствии с MSDN.Используя комментарии на C # и XML, вы легко можете сгенерировать такую ​​документацию.

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

public abstract class Widget
{
    public void PerformAction()
    {
        this.PerformActionImpl();
    }

    protected virtual void PerformActionImpl(){}
}

Где Impl - это сокращение от "Внедрение".Лично мне не нравится этот стиль именования, так что не используйте его, но я уверен, что я читал его где-то наполовину авторитетно, так как это "единственный" способ сделать это.

Я бы не стал использоватьв любом случае, в любом случае это то, что вам действительно нужно для Factory или AbstractFactory.

..

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

Обтекание и бросание - полностью допустимая техника обработки исключений.

Дополнительный контекст, предоставляемый типом самого исключения, вполне может быть достаточным для направления исключения соответствующему обработчику.т. е. вы преобразовали исключение в WidgetException, которое, как можно ожидать, имеет контекст в вашем приложении.Так что это вполне может быть достаточно.

Где вы сделали обертывание, с которым я, однако, не согласен.

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

Код в его нынешнем виде делает некоторые массивные предположения о причине исключения и в этом смысле делает любое использование пользовательского исключения рядом с бесполезным.т. е. теперь все является WidgetException.

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

Так что в отношении сквозной заботы об обработке исключений, я не думаю, что вам следует так много искать шаблон, который облегчит вашу жизнь, а скорее структуру, чтобы абстрагироваться от всего этого.,

Например, Библиотека предприятия.

1 голос
/ 25 января 2011

В приведенном выше коде есть несколько различных шаблонов. Помимо прочего, он выглядит как шаблон Abstract Factory , т. Е. У вас есть абстрактный класс, который реализует фабричный метод, который возвращает конкретные объекты, которые реализуют определенный интерфейс.

Что касается того, является ли подобная обработка исключений хорошей идеей или нет - я склонен согласиться с другими людьми, что обычно я не вижу большой ценности в этом подходе. Я вижу, что вы пытаетесь сделать, а именно предоставить единственное исключение для обработки, подобно тому, как CreateFoo () возвращает один интерфейс (IFoo). Но единственное преимущество, которое я могу придумать, заключается в том, что вы предоставляете некоторую интересную и актуальную информацию по устранению неполадок в WidgetException (например, некоторые строки подключения к базе данных или службе или некоторая специальная логика обработки вокруг трассировки стека). Если вы просто оборачиваете исходное исключение, чтобы ваши клиенты могли иметь дело с WidgetException, вы на самом деле не достигли многого: они могли бы так же легко справиться с базовым типом Exception.

...