您在这里遇到的是与“关注点分离”相关的问题。“车辆”概念有一些基本操作,您可以识别其中一些,例如“加速”。现在“加速”的实现取决于某些参数,例如最大扭矩,制动马力等......
这些应该封装在车外……但为什么呢?好吧,因为他们的 Vehicle 代表了一个概念,而不是一个实现。无论涉及哪种类型的汽车,加速都将以相同的方式使用发动机。让我用一个真实的例子:麦克拉伦 F1 是一辆汽车,实际上它是一辆汽车,它包含一个引擎、一个底盘、一些轮胎和悬架等......大众高尔夫 GTI 是一辆汽车,在事实上它是一辆汽车,它包含一个发动机,有一个底盘,有一些轮胎和悬架等......
用户会以与另一辆车完全相同的方式驾驶一辆车,即使它具有截然不同的组件集。用户甚至不需要知道大部分细节。这就是为什么您需要将您的车辆概念与由您的车辆特定组件封装的实现细节分开的原因。你也应该为你的“刹车”做同样的事情,你应该在构造时将引擎和刹车注入车辆(查找依赖注入)。
现在来看看颜色:我建议你把它放在你的类层次结构的顶层,在 Vehicle 抽象类中。它适用于所有类型的车辆,并且所有人都以相同的方式使用,并且不影响任何实施。它可能应该通过构造函数进行设置,并repaint
提供用于更改它的函数(当然,一旦必要的费用通过 SalesPoint 传递到车库!)。
所以最后的课程可能看起来像这样......
class Vehicle
{
private:
std::unique_ptr<Engine> engine;
std::unique_ptr<Brake> brakes; // same for "Suspension", "Chassis" etc...
VehicleColour colour; // An enum defined here or elsewhere.
public:
Vehicle( std::unique_ptr<Engine> engine, std::unique_ptr<Brake> brakes, VehicleColour colour)
: this->engine(std::move(engine)),
this->brakes(std::move(brakes)),
this->colour(colour) {
}
virtual void Start(const Key& key) {
engine->ignition( key );
brakes->disengage();
}
virtual void Break( BreakPattern pattern ) {
engine->setThrottlePosition( NO_THROTTLE );
brakes->engage( pattern ); // e.g. SIMPLE_HARMONIC, or SLAM... brakes may have ABS or not but you don't need to know
}
virtual void Accelerate() {
brakes->disengage();
engine->setThrottlePosition( TO_THE_METAL );
}
};
使用它:
std::unique_ptr<Brake> absBrakes( new VwAbsDiskBrakes() );
std::unique_ptr<Engine> fastEngine( new TurboV8( FOUR_LITRE ) );
Vehicle hotrod( absBrakes, fastEngine, RED );
hotrod.start();
hotrod.accelerate();
它通过它们的接口使用组件,所以它不需要知道细节。Vehicle 的子类不需要担心任何不是 Vehicle 特定的东西。如果有车辆不符合您的通用概念车辆(例如,如果有一辆没有刹车的车辆),您将只需要车辆的子类。