Refactoring a Switch Statement
来源:互联网 发布:mac airplay在哪里设置 编辑:程序博客网 时间:2024/05/19 20:42
Introduction
This article describes refactoring a switch
statement in order to reduce Cyclomatic complexity.
Background
Many developers would have scratched their heads in order to keeptheir Cyclomatic complexity under 10. In some cases, it is really notpossible at first site. In this article, I have provided a way to dothat. Take the example of a Device State machine. You have a number ofdevice states as below:
public enum DeviceStatesEnum
{
PowerUp,
Waiting,
StandBy,
Inactive,
Active,
Start,
Ready,
Equilibrating,
StartRunning,
Running,
ShoutingDown,
ShoutDown,
WarmingUp,
Error
}
Using the code
Just download the code and run it.
public enum DeviceStatesEnum
{
PowerUp,
Waiting,
StandBy,
Inactive,
Active,
Start,
Ready,
Equilibrating,
StartRunning,
Running,
ShoutingDown,
ShoutDown,
WarmingUp,
Error
}
You have come up with the following class in order to handle the various states:
public class DeviceController
{
private DeviceStatesEnum _currentDeviceState = DeviceStatesEnum.ShoutDown;
public void ChangeDeviceState(DeviceStatesEnum deviceState)
{
switch (deviceState)
{
case DeviceStatesEnum.Active:
SetDeviceStateToActive();
break;
case DeviceStatesEnum.Equilibrating:
SetDeviceStateToEquilibrating();
break;
case DeviceStatesEnum.Error:
SetDeviceStateToError();
break;
case DeviceStatesEnum.Inactive:
SetDeviceStateToInactive();
break;
case DeviceStatesEnum.PowerUp:
SetDeviceStateToPowerUp();
break;
case DeviceStatesEnum.Ready:
SetDeviceStateToReady();
break;
case DeviceStatesEnum.Running:
SetDeviceStateToRunning();
break;
case DeviceStatesEnum.ShoutDown:
SetDeviceStateToShoutDown();
break;
case DeviceStatesEnum.ShoutingDown:
SetDeviceStateToShoutingDown();
break;
case DeviceStatesEnum.StartRunning:
SetDeviceStateToStartRunning();
break;
}
}
public DeviceStatesEnum GetDeviceState()
{
return _currentDeviceState;
}
private void SetDeviceStateToStartRunning()
{
if(_currentDeviceState == DeviceStatesEnum.Ready)
_currentDeviceState = DeviceStatesEnum.StartRunning;
}
private void SetDeviceStateToShoutingDown()
{
_currentDeviceState = DeviceStatesEnum.ShoutingDown;
}
private void SetDeviceStateToShoutDown()
{
_currentDeviceState = DeviceStatesEnum.ShoutDown;
}
private void SetDeviceStateToRunning()
{
if (_currentDeviceState == DeviceStatesEnum.StartRunning )
{
_currentDeviceState = DeviceStatesEnum.Running;
}
}
private void SetDeviceStateToReady()
{
if (_currentDeviceState == DeviceStatesEnum.Equilibrating )
{
_currentDeviceState = DeviceStatesEnum.Ready;
}
}
private void SetDeviceStateToPowerUp()
{
if (_currentDeviceState != DeviceStatesEnum.Error)
_currentDeviceState = DeviceStatesEnum.PowerUp;
}
private void SetDeviceStateToInactive()
{
if(_currentDeviceState != DeviceStatesEnum.Error)
_currentDeviceState = DeviceStatesEnum.Inactive;
}
private void SetDeviceStateToError()
{
_currentDeviceState = DeviceStatesEnum.Error;
}
private void SetDeviceStateToEquilibrating()
{
if (_currentDeviceState == DeviceStatesEnum.Active)
{
_currentDeviceState = DeviceStatesEnum.Equilibrating;
}
}
private void SetDeviceStateToActive()
{
if (_currentDeviceState != DeviceStatesEnum.Error)
{
_currentDeviceState = DeviceStatesEnum.Active;
}
}
}
Since you have 14 states, you will end up having a Cyclomaticcomplexity more than 14. Here is the way to reduce this complexity to1. Do the following changes in the above class DeviceController
. Declare a Dictionary
.
private Dictionary<DeviceStatesEnum, Action> _deviceStateHandler =
new Dictionary<DeviceStatesEnum, Action>();
Add a constructor to create a mapping with the states.
public DeviceController()
{
_deviceStateHandler.Add(DeviceStatesEnum.Active, new Action(SetDeviceStateToActive));
_deviceStateHandler.Add(DeviceStatesEnum.Equilibrating,
new Action(SetDeviceStateToEquilibrating));
_deviceStateHandler.Add(DeviceStatesEnum.Error, new Action(SetDeviceStateToError));
_deviceStateHandler.Add(DeviceStatesEnum.Inactive,
new Action(SetDeviceStateToInactive));
_deviceStateHandler.Add(DeviceStatesEnum.PowerUp, new Action(SetDeviceStateToPowerUp));
_deviceStateHandler.Add(DeviceStatesEnum.Ready, new Action(SetDeviceStateToReady));
_deviceStateHandler.Add(DeviceStatesEnum.Running, new Action(SetDeviceStateToRunning));
_deviceStateHandler.Add(DeviceStatesEnum.ShoutDown,
new Action(SetDeviceStateToShoutDown));
_deviceStateHandler.Add(DeviceStatesEnum.ShoutingDown,
new Action(SetDeviceStateToShoutingDown));
_deviceStateHandler.Add(DeviceStatesEnum.StartRunning,
new Action(SetDeviceStateToActive));
//TODO
//Create mapping for all the states
}
Then, change the ChangeDeviceState
as below:
public void ChangeDeviceState(DeviceStatesEnum deviceState)
{
_deviceStateHandler[deviceState].Invoke();
}
Now the Cyclomatic complexity of the method ChangeDeviceState
is one.
License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)
About the Author
rajeshjj
- Refactoring a Switch Statement
- Refactoring - replace Switch statement with state/strategy
- Can we put a continue in a switch-case statement?
- switch引发的错误 a label can only be part of a statement and a declaration is not a statement
- switch引发的错误:a label can only be part of a statement and a declaration is not a statement
- switch 错误:a label can only be part of a statement and a declaration is not a statement
- switch引发的错误 a label can only be part of a statement and a declaration is not a statement
- switch引发的错误 a label can only be part of a statement and a declaration is not a statement
- A Target for Refactoring
- Using the Switch Statement
- A statement
- 转:switch引发的错误:a label can only be part of a statement and a declaration is not a statement
- java7新特性之—String values in a switch statement
- Validates using resource IDs in a switch statement in Android library module
- Resource IDs cannot be used in a switch statement in Android library modules
- The switch statement of JavaScript
- Refactoring
- Refactoring
- 从孙子兵法谈企业管理
- 最简单的定时关机
- 6个变态的C语言Hello World程序
- 巧妙利用TWebBrowser让程序直接显示网络图片(Delphi)
- 经过验证的python发送邮件程序
- Refactoring a Switch Statement
- CAS Server配置数据库用户验证方式示例
- 为备份或还原操作指定的设备太多;只允许指定64个设备。RESTORE DATABASE操作异常
- DelegateAndEvent应用之回马枪
- 毛毛的生活
- 安装 Fatal error: Maximum execution time of 30 seconds exceeded in …/magento/lib/Varien/Db/Adapter/Pdo/Mysql.php on line 230
- poj 3006有灌水了哈!这道题其实挺有意思
- 临时总结
- GET和POST区别详解