Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Примеры обработки исключительных ситуаций




Прежде всего, имеет смысл определить для них специальный класс. Простейшим вариантом является класс, который может хранить код ошибки:

class Exception{public:enum ErrorCode {NO_MEMORY,DATABASE_ERROR,INTERNAL_ERROR,ILLEGAL_VALUE};Exception(ErrorCode errorKind,const String&errMessage);ErrorCode GetErrorKind(void)const {return kind;};const String&GetErrorMessage(void)const{return msg;};private:ErrorCode kind;String msg;};

Создание исключительной ситуации будет выглядеть следующим образом:

if (connect(serverName)==false)throw Exception(Exception::DATABASE_ERROR,serverName);А проверка на исключительную ситуацию так:try {...}catch (Exception&e){cerr <<"Произошла ошибка "<<e.GetErrorKind()<<"Дополнительная информация:"<<e.GetErrorMessage();}

Преимущества класса перед просто целым числом состоят, во-первых, в том, что передается дополнительная информация и, во-вторых, в операторах catch можно реагировать только на ошибки определенного вида. Если была создана исключительная ситуация другого типа, например

throw AnotherException;

то блок catch будет пропущен: он ожидает только исключительных ситуаций типа Exception. Это особенно существенно при сопряжении нескольких различных программ и библиотек – каждый набор классов отвечает только за собственные ошибки.

В данном случае код ошибки записывается в объекте типа Exception. Если в одном блоке catch ожидается несколько разных исключительных ситуаций, и для них необходима разная обработка, то в программе придется анализировать код ошибки с помощью операторов if или switch.

try {...}catch (Exception&e){cerr <<"Произошла ошибка "<<e.GetErrorKind()<<"Дополнительная информация:"<<e.GetErrorMessage();if (e.GetErrorKind()==Exception::NO_MEMORY ||e.GetErrorKind()==Exception::INTERNAL_ERROR)throw;else if (e.GetErrorKind()==Exception::DATABASE_ERROR)return TRY_AGAIN;else if (e.GetErrorKind()==Exception::ILLEGAL_VALUE)

return NEXT_VALUE;}

 

Паттерны и их классификация.

ПРИНЦИП КЛАССИФИКАЦИИ ПАТТЕРНОВ ПРОЕКТИРОВАНИЯ

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

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

Низшим уровнем представления данной системы является описание ее в терминах классов (со своими атрибутами и операциями) и соответствующих им обьектов, выступающих в качестве "микроскопических" элементов, и отношений между ними, играющих роль связей, см. раздел 7.2. Примером "макроскопического " элемента следующего уровня является системная архитектура, представляющая собой базовую подструктуру рассматриваемой системы. Самым высоким уровнем является интеграция отдельных систем, которые в данном случае рассматриваются в качестве макроскопических элементов.

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

Следует упомянуть, что, поскольку паттернов проектирования полифункциональны, то выделение основных функций с целью отнесения отдельного паттерна к той или иной группе было проведено с некоторой долей субъективности. Дополнительные функции паттерна, как правило, приведены в описании данного паттерна.

ПАТТЕРНЫ ПРОЕКТИРОВАНИЯ КЛАССОВ/ОБЬЕКТОВ

Согласно классификации, предложенной в предыдущем разделе, описание системы в терминах классов/обьектов следует считать низшим уровнем ее представления. В свою очередь, при моделировании системы на уровне классов/обьектов обычно проводят дополнительную типологизацию в двух аспектах, а именно, описывают структуру системы в терминах микроскопических элементов (см. раздел 2) и то, каким образом такая система обеспечивает требуемый функционал. Соответственно, среди паттернов проектирования выделены структурные паттерны, см. раздел 3.1 и паттерны распределения обязанностей между классами/объектами, 3.2. Поскольку отдельные объекты создаются и уничтожаются в процессе работы системы, выделена еще одна большая группа паттернов проектирования, которые служат для создания обьектов, 3.3.

Необходимо отметить наличие еще одной классификации паттернов, которое очевидно из наименования данного раздела: паттерны проектирования классов и паттерны проектирования обьектов (определения класса и объекта см. в разделе 7.2). В качестве примера паттернов проектирования классов можно привести "Фабричный метод", "Шаблонный метод"; паттернов проектирования обьектов - "Абстрактную фабрику", "Хранителя" и др.

Кроме этого необходимо отметить, что некоторые паттерны проектирования обьектов часто используются совместно, например, паттерн "Компоновщик" часть применяется вместе с "Итератором" или "Посетителем". Помимо этого, одну и ту же задачу можно решить используя различные паттерны проектирования классов/обьектов в качестве альтернативы, так, например, "Прототип" зачастую используют вместо "Абстрактной фабрики".

 

 

Абстрактная фабрика.

Фабрика, по сути, это виртуальный конструктор. Предположим, у нас есть базовый класс и несколько его наследников. Мы хотим создавать объекты наследников, скрывая их за указателем на базовый класс. Кроме того, мы хотим, чтобы тип наследника определялся в динамике через какой-то параметр. Например, через строковое имя класса, как это сделано в моем примере.

#include <iostream>

#include <string>

#include <map>

#include <boost/shared_ptr.hpp>

template <class TBase>

class TFactory

{ public:

typedef boost::shared_ptr<TBase> BasePtr;

template <class TDerived>

void Register(const std::string& name)

{ m_FactoryContainer[name] = BaseTypePtr(new TDerivedType<TDerived>); }

BasePtr Create(const std::string& name)

{ return m_FactoryContainer[name]->Create(); }

private:

class BaseType

{ public:

virtual ~BaseType() {}

virtual BasePtr Create() const = 0; };

typedef boost::shared_ptr<BaseType> BaseTypePtr;

template <class T>

class TDerivedType: public BaseType

{ public:

virtual BasePtr Create() const

{ return new T; } };

typedef std::map<std::string, BaseTypePtr> FactoryContainer;

FactoryContainer m_FactoryContainer; };

class Furniture {

public:

~Furniture() {}

virtual void ShowName() = 0; };

class Table: public Furniture

{public:

virtual void ShowName()

{ std::cout << "Table" << std::endl; }};

class Chair: public Furniture

{public:

virtual void ShowName()

{std::cout << "Chair" << std::endl; }};

int main()

{ typedef TFactory<Furniture> FurnitureFactory;

typedef FurnitureFactory::BasePtr FurniturePtr;

FurnitureFactory factory;

factory.Register<Table>("Table");

factory.Register<Chair>("Chair");

FurniturePtr f1 = factory.Create("Table");

FurniturePtr f2 = factory.Create("Chair");

f1->ShowName();

f2->ShowName();

return 0;}

Итак, каждый наследник должен зарегистрироваться в фабрике и передать ей свой идентификатор. После этого фабрика может создавать объекты данного типа.

На мой взгляд, фабрика — ненужный паттерн.

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

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...