Trains design

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
(Design Critique)
(Design Critique)
Line 36: Line 36:
 
* The use of [[singleton]] in EngineModes is not appropriate.  It appears to use an ID to identify which Locomotive the calls are coming from (presumably so it can do things such as set speed).  It would be better to remove the [[singleton]].  Each instance should store the properties of the Locomotive that it operates on including speed.  Each EngineMode would then belong to just one Locomotive which is [[model the real world|modelling the real world]] more effectively.
 
* The use of [[singleton]] in EngineModes is not appropriate.  It appears to use an ID to identify which Locomotive the calls are coming from (presumably so it can do things such as set speed).  It would be better to remove the [[singleton]].  Each instance should store the properties of the Locomotive that it operates on including speed.  Each EngineMode would then belong to just one Locomotive which is [[model the real world|modelling the real world]] more effectively.
 
* The use of [[composite]] pattern would allow MultipleUnits of MultipleUnits to be constructed.  It seems from the text that this wouldn't be allowed.  It is not the most effective way of capturing this abstraction if it is indeed allowed.  The standard [[composite]] pattern would capture this more cleanly.
 
* The use of [[composite]] pattern would allow MultipleUnits of MultipleUnits to be constructed.  It seems from the text that this wouldn't be allowed.  It is not the most effective way of capturing this abstraction if it is indeed allowed.  The standard [[composite]] pattern would capture this more cleanly.
 +
* RailVehicles are responsible for a couple of roles that could be separated.  It performs the actual functions of RailVehicles which is fine.  However, it is also aware of it's own structure in relation to other RailVehicles (the next and previous).  If we aim to separate concerns this should not be the case, but this solution is possibly modeling the real world quite accurately.
 +
* Wagon and it's subclasses are meant to be a [[bridge]], but they provide functionality not in the interface of RollingStock (if the diagram is assumed to be complete).  Using this functionality will require accessing the Wagon directly.  Methods should be added to the interface of RollingStock to support these functions if they are intended to be accessed.

Revision as of 21:09, 4 October 2009

An OO model of trains. This design appeared in the 2007 427 exam.

Trains.png

Design notes

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.

GoF Design Patterns

  • Bridge - the RollingStock is the Bridge pattern where Wagon and its subclasses are the implementation. The wagon is also kind of a State, since BoxCar and Van encapsulate a state of wagon.
  • Composite - Locomotive can be a Slug or MultipleUnit, MultipleUnit contains two Locomotives.
  • Chain of Responsibility - RailVehicle getLocation(), passed along chain of RailVehicles until it reaches the Locomotive.
  • Singleton - Warming and Hot
  • Adapter - InactiveLoco and Locomotive. Is maybe also a Proxy, since siblings that does a lazy initialization pattern.
  • Chain of Responsibility - brake() of the the RailVehicle, since it is passed to every single RailVehilce and applied by each RailVehilce it is a modified Chain of Responsibility pattern.
  • Mediator - CTC and Locomotive
  • State - Warming and Hot

Design Critique

  • The LastCar class appears to be an irrelevant class, it only adds a single boolean which could be in the BoxCar class instead.
  • Train has a caboose which is defined as a LastCar, it should really Program to the interface not the implementation and define a Wagon.
  • Slug breaks the Avoid no-op overrides heuristic, however this is part of the Composite pattern.
  • The use of singleton in EngineModes is not appropriate. It appears to use an ID to identify which Locomotive the calls are coming from (presumably so it can do things such as set speed). It would be better to remove the singleton. Each instance should store the properties of the Locomotive that it operates on including speed. Each EngineMode would then belong to just one Locomotive which is modelling the real world more effectively.
  • The use of composite pattern would allow MultipleUnits of MultipleUnits to be constructed. It seems from the text that this wouldn't be allowed. It is not the most effective way of capturing this abstraction if it is indeed allowed. The standard composite pattern would capture this more cleanly.
  • RailVehicles are responsible for a couple of roles that could be separated. It performs the actual functions of RailVehicles which is fine. However, it is also aware of it's own structure in relation to other RailVehicles (the next and previous). If we aim to separate concerns this should not be the case, but this solution is possibly modeling the real world quite accurately.
  • Wagon and it's subclasses are meant to be a bridge, but they provide functionality not in the interface of RollingStock (if the diagram is assumed to be complete). Using this functionality will require accessing the Wagon directly. Methods should be added to the interface of RollingStock to support these functions if they are intended to be accessed.
Personal tools