Я делаю дизайн OO-фреймворка и сталкиваюсь со следующей проблемой.
Допустим, в фреймворке у меня есть Shape интерфейс и пользователи свободныреализовывать и расширять (добавляя новые функции) интерфейс Shape для создания собственных фигур, например Square и Circle .Чтобы сделать эти новые объекты доступными, пользователи должны зарегистрировать их в ShapeFactory с указанием имени фигуры (строки) и объекта.
Кроме того, инфраструктура предоставляет интерфейс под названием ShapeWorker , который определяет следующую функцию:
class ShapeWorker
{
public:
void processShape( Shape& shape ) = 0;
};
Пользователи могут свободно реализовывать интерфейс ShapeWorker , чтобы сделать конкретную рабочую фигуру, например, SquareWorker и CircleWorker .Чтобы сделать эти новые объекты доступными, пользователи должны зарегистрировать их в WorkerFactory , указав имя формы (строки) и объекта.
В определенный момент каркас, учитываяСтрока, представляющая имя фигуры, создает новую Shape , используя ShapeFactory , а затем (где-то еще в коде) создает новую ShapeWorker , используя WorkerFactory с тем же именем фигуры.Затем вызывается processShape , обеспечивающий созданный ранее экземпляр Shape .
[ ... ]
Shape* myShape = shapeFactory.create( shapeName );
[ ... ]
ShapeWorker* myWorker = workerFactory.create( shapeName );
myWorker->processShape( *myShape );
[ ... ]
Дело в том, что, делая это, я заставляю пользователя, например, реализовывать SquareWorker для выполнения преобразования с Shape до Square в processShape , чтобы получить доступ к полной SquareИнтерфейс :
class SquareWorker
{
public:
void processShape( Shape& shape )
{
Square& square = dynamic_cast< Square& >( shape );
// using Square interface
}
};
Это противоречит принципу подстановки Лискова.
Теперь, этот подход неправильный?Какое это было бы лучшее решение?Обратите внимание, что я не хочу реализовывать processShape как функцию-член Shape .
Надеюсь, описание достаточно ясное.
Заранее благодарим за вашепомощь.
Симо