2010-01-26 4 views
6

Недавно я писал код, подобный этому:Абстрактный класс - пряча реализация в C++ практике

messagehandler.h:

#include "message.h" 
class MessageHandler { 
public: 
    virtual ~MessageHandler() {} 
    virtual void HandleMessage(Message *msg) = 0: 
}; 

persistmessagehandler.h:

MessageHandler *CreatePersistMessageHandler(); 

persistmessagehandler. cpp:

#include "messagehandler.h" 
#include "persist.h" 

class PersistMessageHandler : public MessageHandler { 
private: 
    PersistHandle ph; 
    size_t count; 
    InternalCheck(); 
public: 
    PersistMessageHandler(int someParam); 
    virtual ~PersistMessageHandler(); 
    virtual void HandleMessage(Message *msg): 
}; 
PersistMessageHandler::PersistMessageHandler(int someParam) 
{ 
    ph.Initialize(); 
} 
... rest of implementation. 

MessageHandler *CreatePersistMessageHandler(int someParam) 
{ 
    return new PersistMessageHandler(someParam); 
} 

Здесь нужно скрыть PersistMessageHandler. Клиентам не нужно включать заголовок для класса PersistMessageHandler, при этом все включенные и типы реализации могут потребоваться, а также более четкое разделение интерфейса и реализации. . Это всегда будет динамически распределено,

Все пользователи PersistMessageHandler просто вызовут CreatePersistMessageHandler (..); прямо или косвенно получить его с завода.

Но. Я не видел, чтобы этот подход использовался в других местах. Является ли вышеуказанная хорошая практика? Существуют ли другие/лучшие альтернативы для простых случаев?

+0

Почему кто-нибудь когда-либо сокращал «Сообщение» на «Messge»? Это опечатка? – unwind

+0

Отличный вопрос! Я делаю это все время и всегда задавался вопросом, был ли он кошерным.За исключением моего объявления: 'std :: auto_ptr CreatePersistMessageHandler();' –

+0

См. Также http://stackoverflow.com/questions/825018/pimpl-idiom-vs-pure-virtual-class-interface – Frank

ответ

6

Вам всегда нужно скрывать как можно больше. Ваш путь (ввод классов реализации в .cpp) является обычным способом сделать это в C++.

1

Уверенный - это выглядит как a form of the factory pattern. Пользователи фабрики не интересуются ее внутренними деталями, они заботятся только о вещах, которые она создает.

2

Это хороший способ скрыть детали реализации от ваших клиентов. Если вы работаете в Windows, вы также можете использовать __interface вместо абстрактного базового класса.

Интерфейс - это расширение компилятора MSVC, которое выглядит как абстрактный базовый класс, но имеет разные правила для создания и уничтожения, чем обычный класс C++. Это стандартный способ работы в Windows, поэтому есть средства, поддерживаемые системой для работы с объектами вне процесса и для их использования в коде .NET.

1

Процесс скрытия деталей реализации называется Encapsulation. Процесс минимизации зависимостей построения для ваших пользователей называется Insulation. Существует большая (но старение) книга Джона Lakos посвящен оба тема:

http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620

0

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

Недостатком использования ABC является то, что вы теряете семантику значений вашего класса, которая может быть или не может быть приемлемой/желательной.

Один из методов, который также скрывает детали реализации без этого недостатка, - Pimpl. Угадайте, вы должны знать.

Я предпочитаю ABC в большинстве случаев.

+0

@CraigMcQueen typo , должен быть ABC (абстрактный базовый класс). Благодаря! –

Смежные вопросы