Немного отвлечемся от нашей игры. Пусть Ваша программа управляет файлами в различных файловой системе, для чего Вы от класса CFile порождаете потомки CFATFile и CNTFSFile. А еще файлы могут быть либо текстовыми, либо двоичными - да еще и в каждой файловой системой. Если просто порождать потомки, то получится уже четыре класса. Кроме того, код будет дублировать друг друга, а подклассы окажутся привязанными к реализации - поскольку никто не гарантирует одинакового поведения для CFATTextFile и CNTFSTextFile.
Выход в разделении файловых систем и вида файла в разные иерархии классов. То есть, пусть от CFile порождены CFATFile и CNTFSFile, но не более. А классы текстовых и двоичных файлов CTextFile и CBinFile порождены от CAbstractFile, который содержит в себе указатель на CFile. Теперь операции текстовых и двоичных файлов вызывают виртуальные функции CFile - а исполняются те, что нужно. Пример кода таков (не проверял):
// Это классы отвечающие за физическую реализацию class CFile { public: virtual void doIt1 () = 0; virtual void doIt2 () = 0; }; // В конкретных классах виртуальные функции // исполняют несколько полезных вещей непосредственно // с файловой системой. class CFATFile : public CFile { public: void doIt1 () { format("c:"); }; void doIt2 () { loadVirus("OneHalf"); }; }; class CNTFSFile : public CFile { public: void doIt1 () { mustdie("windows"); }; void doIt2 () { catchHim("Bill"); }; }; // А это классы, отвечающие за файлы на более высоком уровне class CAbstractFile : { public: virtual void processFile () = 0; private: // Аргегация низкоуровневого файла CFile* m_file; }; class CTextFile : public CAbstractFile { public: // В зависимости от класса m_file исполнятся // разные функции void processFile () { m_file->doIt1(); }; }; class CBinFile : public CAbstractFile { public: void processFile () { m_file->doIt2(); }; };
Таким образом паттерн Мост (Bridge) разделяет абстракцию и ее реализацию. Вот структура паттерна.