An OO model of trains. This design appeared in the 2007 427 exam.
This is a preliminary design for managing railway Trains. Each Train consists of an optional Locomotive and some RollingStock (i.e. railway vehicles that can’t move themselves). In North American installations, a Train may also have a caboose, which is just the last wagon fitted with a flashing light.
- Locomotives and RollingStock are RailVehicles. Each RailVehicle knows the RailVehicle coupled immediately before and after it. These next and prev references are set by the join() method.
- When a RailVehicle is told to brake(), it applies its own brakes and also passes the message to its next RailVehicle, if one exists.
- Similarly, when a RailVehicle is asked to getLocation(), it forwards the request to its prev RailVehicle, if one exists. When the request reaches the Locomotive at the front of the train, it returns its location.
- A Locomotive pulls or pushes a Train. The startEngine() method must be called, then setSpeed() tells it what speed to accelerate to. A negative speed indicates reverse.
- Locomotives that have not fully warmed up to operating temperature should be handled more gently. This is achieved by forwarding engine commands to an EngineMode, which is either Warming or Hot. Other Locomotive behaviours depend on what kind of Locomotive it is, as indicated by the model number.
- Locomotives regularly report their changes of location to a CentralTrafficControl object, which can slow or stop trains to avoid collisions and congestion.
- When two Locomotives are used together, they form a MultipleUnit.
- The front Locomotive is known as the aUnit and the second as the bUnit.
- A Slug has no engine, so overrides startEngine() to do nothing. It can only be used as a bUnit, because it needs a power source from an aUnit.
- RollingStock implementations differ depending on user preference. North American installations typically use BoxCars, while elsewhere Vans are used.
- Sometimes an unused or broken Locomotive is pulled as if it were RollingStock. InactiveLoco caters for this situation.