f



nested switch statements



The method DetermineAutoPilotMode is called at interval.   FlightMode and D=
eviceID are determined at run time and is static through flight.   SpaceShi=
pMode and AutoPilotMode are dynamic - i.e change during the flight trajecto=
ry.   I've scanned a handful of articles on how to restructure a design pre=
dicated on switch statements but not sure how the solutions apply to this c=
ase.  I know switch statements are not necessarily bad but any recommendati=
ons on how to restructure this (design patterns ....) would be appreciated.=
 =20


void SpaceShip::DetermineAutoPilotMode()
{
  switch ( SpaceShipMode )
  {
  case Standby :
    {
      std::cout << " switch ( SpaceShipMode ) / Standby " << "\n";
      AutopilotMode =3D Off;
    }
    break;
  case Launch  :
    {
      std::cout << " switch ( SpaceShipMode ) /  Launch " << "\n";
      AutopilotMode =3D Setup;
    }
    break;
  case Flight  :
    {
      switch ( AutopilotMode )
      {
      case Terminal :
        {
          std::cout << " switch ( SpaceShipMode ) / Flight / switch ( Autop=
ilotMode ) / Terminal " << "\n";
          AutopilotMode =3D  Decorrelation;
        }
        break;
      case Off :
      case Midcourse     :
      case Decorrelation :
      case InitialTurn   :
        {
          if ( CorrelationTimeDelay )
          {
            AutopilotMode  =3D Terminal;
            switch ( FlightMode )
            {
            case ALD :
              {
                std::cout
				  << " switch ( SpaceShipMode ) / Flight / switch ( AutopilotMode ) / I=
nitialTurn / switch ( FlightMode ) / ALD " << "\n";
              }
              break;
            case ALH :
              {
               std::cout
				  << " switch ( SpaceShipMode ) / Flight / switch ( AutopilotMode ) / I=
nitialTurn / switch ( FlightMode ) / ALH " << "\n";
              }
              break;
            default : break ;
            };
          }
          else
          {
            switch ( DeviceID )
            {
            case DID1 :
            case DID2 :
              {
                std::cout
				  << " switch ( SpaceShipMode ) / Flight / switch ( AutopilotMode ) / I=
nitialTurn / switch ( DeviceID ) / DID1 | DID2 " << "\n";
              }
            break;
            case DID3 :
              {
                std::cout
				  << " switch ( SpaceShipMode ) / Flight / switch ( AutopilotMode ) / I=
nitialTurn / switch ( DeviceID ) / DID3 " << "\n";
              }
              break;
            default : break ;
            };
          }
        }
      break ;
      default : break ;
      };
    }
    break;
  case Unknown :
    {
      std::cout << " switch ( SpaceShipMode ) / Unknown  " << "\n";
    }
    break;
  default : break ;
  };
}
0
forumsmp
12/22/2016 3:58:46 PM
comp.lang.c++ 49423 articles. 7 followers. Post Follow

1 Replies
560 Views

Similar Articles

[PageSpeed] 38

On 22.12.16 16.58, forumsmp@gmail.com wrote:
> The method DetermineAutoPilotMode is called at interval.   FlightMode and DeviceID are determined at run time and is static through flight.   SpaceShipMode and AutoPilotMode are dynamic - i.e change during the flight trajectory.   I've scanned a handful of articles on how to restructure a design predicated on switch statements but not sure how the solutions apply to this case.  I know switch statements are not necessarily bad but any recommendations on how to restructure this (design patterns ....) would be appreciated.

AFAICS you try to model several dependent state machines.
 From the performance point of view there is nothing wrong with switch.
But doing this in Spaghetti code is error prone. If you miss to 
synchronize one of the mode variables on an unusual mode transition the 
system could end up in an inconsistent state, turning into undefined 
behavior at least at application level. And if you miss to handle one 
combination in one of the sub paths the implementation could be 
incomplete, again UB.

First of all you should split the different levels of operation into 
different functions. This makes the code more readable.

Furthermore calling a function /Determine/AutoPilotMode that depends on 
AutopilotMode is at least misleading. Actually the implementation is 
unstable, because it toggles between Decorrelation and Terminal.

DeviceID sound like something that should not be hard coded at all. But 
it is not clear from your example what the intention behind DeviceID is.

At the next step it could be useful to separate the different state 
machines. I.e. Some code controls the SpaceShipMode and provides actions 
for state transitions. Another code manages the AutopilotMode including 
transitions as well. E.g. it is probably valid to combine AutoPilot Off 
with Launch. If you do so, then there is no more need to /determine/ the 
AutopilotMode at all. It is just there.

Maybe the autopilot handler does not exist at all if it is turned off. 
In this case the mode Off is superfluous.


Just a few suggestions,

Marcel
0
Marcel
12/22/2016 6:52:11 PM
Reply: