建议104:用多态代替条件语句

建议104:用多态代替条件语句

假设要开发一个自动驾驶系统。在设计之初,此自动驾驶系统拥有一个驾驶系统命令的枚举类型:

    enum DriveCommand
    {
        Start,
        Stop
    }

当前该枚举存在两个命令:开始、停止。又假设有一个驾驶方法可以处理车辆接收到的指令。一开始我们可能像下面这样编码:

复制代码
        static void Main(string[] args)
        {
            DriveCommand command = DriveCommand.Start;
            Drive(command);
            command = DriveCommand.Stop;
            Drive(command);

        }

        static void Drive(DriveCommand command)
        {
            if (command == DriveCommand.Start)
            {
                //车辆启动
            }
            else if (command == DriveCommand.Stop)
            {
                //车辆停止
            }
        }
复制代码

有些人可能喜欢用switch语句(当然,switch本质上也是if语句)。

复制代码
        static void Drive(DriveCommand command)
        {
            switch (command)
            {
                case DriveCommand.Start: //车辆启动 break; case DriveCommand.Stop: //车辆停止 break; default: break; } }
复制代码

 随着更多的系统功能不断地被开发出来,我们考虑为车辆加入的命令也越来越多,如下所示:

复制代码
    enum DriveCommand
    {
        Start,
        Stop,
        Pause,
        TurnLeft,
        TurnRight
    }
复制代码

 

随着DriveCommand元素的增加,采用if或switch语句将带来可怕的混乱状态是显而易见的。在一个复杂的控制系统中,命令可能会多达上百条。每增加一条命,我们首先要修改Drive方法。Drive方法将会及其膨胀,而且每行代码几乎是一模一样的:

if 命令

  then 行动

这种情况,我们不得不考虑重构原来的代码。原来的设计理念也是欠妥当的,它不遵守设计模式中的“开闭原则”。开闭原则是指:对扩展开发,对修改关闭。遵从开闭原则的一次重构是,使用多态来规避不断膨胀的条件语句。首先,设计一个抽象类Commander:

    abstract class Commander
    {
        public abstract void Execute();
    }

 

所有的Start或者Stop之类的命令,全部继承自这个抽象类:

复制代码
    class StartCommander : Commander
    {

        public override void Execute()
        {
            //启动
        }
    }

    class StopCommander : Commander
    {

        public override void Execute()
        {
            //停止
        }
    }
复制代码

 

在使用多态后,调用方法的代码应该如下所示:

复制代码
        static void Main(string[] args)
        {
            Commander commander = new StartCommander();
            Drive(commander);
            commander = new StopCommander();
            Drive(commander);
        }

        static void Drive(Commander commander)
        {
            commander.Execute();
        }
复制代码

 

可见,代码简洁了不少,而且,可扩展性增强了。即使未来还需要增加命令,扩展相应的子类就可以了。而且我们关闭了修改,即对Drive方法,即使增加再多的命令,也不需要对其进行修改。

 

 

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值