Есть ли шаблон, который охватывает этот случай специализации
Рассмотрим этот случай специализации, когда менее специализированному классу требуется доступ к объекту типа интерфейса, но более специализированному классу требуется доступ к конкретной реализации этого интерфейса:
class IPropulsionMechanism {
public:
virtual void engage() = 0;
virtual void disengage() = 0;
};
class Engine : public IPropulsionMechanism {
};
class Vehicle {
public:
void travelTo(const Destination& dest) {
mPropulsion.engage();
dest.arrival().wait();
mPropulsion.disengage();
}
void SetPropulsion(IPropulsionMechanism& prop) {
mPropulsion = prop;
}
protected:
IPropulsionMechanism& mPropulsion;
};
class Car : public Vehicle {
void adjustTiming() {
// Propulsion Mechanism MUST be Engine
}
Проблема заключается в том, что автомобиль должен знать детали своего двигателя, он не может работать без него, и все же SetPropulsion
Метод принимает только тип интерфейса.
Некоторый унаследованный код до меня теперь имеет дело с этим, заставляя SetPropulsion
быть контравариантным (через dynamic_cast
в Engine
). Очевидно, этот актерский состав делает SetPropulsion
нарушать принцип Лискова.
Моё предварительное решение - добавить Engine& mEngine
член подкласса, и SetEngine
метод:
void SetEngine(Engine& engine) {
mEngine = engine;
Vehicle::SetPropulsion(engine);
}
Однако мое единственное замечание заключается в том, что у подкласса будет доступ к двум ссылкам на одно и то же (mPropulsion и mEngine).
Обратите внимание, что в отношениях может быть много таких участников, для автомобиля требуется Engine, CarSeat, AirConVentilation и т. Д. но у транспортного средства должен быть механизм IPropulsionMechanism, ISeat и IVentilation и т. д.
Я подозреваю, что есть образец, который уже охватывает эту специализацию. Надеюсь, кто-то может назвать это для меня.