编写高质量代码改善C#程序的157个建议——建议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个建议》陆敏技
编写高质量代码改善C#程序的157个建议——建议104:用多态代替条件语句的更多相关文章
- 编写高质量代码改善C#程序的157个建议[1-3]
原文:编写高质量代码改善C#程序的157个建议[1-3] 前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理 ...
- 读书--编写高质量代码 改善C#程序的157个建议
最近读了陆敏技写的一本书<<编写高质量代码 改善C#程序的157个建议>>书写的很好.我还看了他的博客http://www.cnblogs.com/luminji . 前面部 ...
- 编写高质量代码改善C#程序的157个建议——建议157:从写第一个界面开始,就进行自动化测试
建议157:从写第一个界面开始,就进行自动化测试 如果说单元测试是白盒测试,那么自动化测试就是黑盒测试.黑盒测试要求捕捉界面上的控件句柄,并对其进行编码,以达到模拟人工操作的目的.具体的自动化测试请学 ...
- 编写高质量代码改善C#程序的157个建议——建议156:利用特性为应用程序提供多个版本
建议156:利用特性为应用程序提供多个版本 基于如下理由,需要为应用程序提供多个版本: 应用程序有体验版和完整功能版. 应用程序在迭代过程中需要屏蔽一些不成熟的功能. 假设我们的应用程序共有两类功能: ...
- 编写高质量代码改善C#程序的157个建议——建议155:随生产代码一起提交单元测试代码
建议155:随生产代码一起提交单元测试代码 首先提出一个问题:我们害怕修改代码吗?是否曾经无数次面对乱糟糟的代码,下决心进行重构,然后在一个月后的某个周一,却收到来自测试版的报告:新的版本,没有之前的 ...
- 编写高质量代码改善C#程序的157个建议——建议154:不要过度设计,在敏捷中体会重构的乐趣
建议154:不要过度设计,在敏捷中体会重构的乐趣 有时候,我们不得不随时更改软件的设计: 如果项目是针对某个大型机构的,不同级别的软件使用者,会提出不同的需求,或者随着关键岗位人员的更替,需求也会随个 ...
- 编写高质量代码改善C#程序的157个建议——建议153:若抛出异常,则必须要注释
建议153:若抛出异常,则必须要注释 有一种必须加注释的场景,即使异常.如果API抛出异常,则必须给出注释.调用者必须通过注释才能知道如何处理那些专有的异常.通常,即便良好的命名也不可能告诉我们方法会 ...
- 编写高质量代码改善C#程序的157个建议——建议152:最少,甚至是不要注释
建议152:最少,甚至是不要注释 以往,我们在代码中不写上几行注释,就会被认为是钟不负责任的态度.现在,这种观点正在改变.试想,如果我们所有的命名全部采用有意义的单词或词组,注释还有多少存在的价值. ...
- 编写高质量代码改善C#程序的157个建议——建议151:使用事件访问器替换公开的事件成员变量
建议151:使用事件访问器替换公开的事件成员变量 事件访问器包含两部分内容:添加访问器和删除访问器.如果涉及公开的事件字段,应该始终使用事件访问器.代码如下所示: class SampleClass ...
- 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法
建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...
随机推荐
- 【UVa】1343 The Rotation Game(IDA*)
题目 题目 分析 lrj代码.... 还有is_final是保留字,害的我CE了好几发. 代码 #include <cstdio> #include <algorit ...
- JS-基础2
JS基本语法 1.学习javascript的目的? A.增强网页的动态效果. B.改变网页中的元素(能够直接对网页中的元素进行操作). C.加强同后台的数据交互.页面的数据验证. 2.JS在web ...
- java实现时钟
package com.js.ai.modules.pointwall.testxfz; import java.awt.Color; import java.awt.Dimension; impor ...
- socket-简单实现
server--------------#!/usr/bin/env python # encoding: utf-8 # Date: 2018/6/7 from socket import * s ...
- 修改win7远程桌面端口号
Windows 7/Vista/XP/2003等系统中的远程终端服务是一项功能非常强大的服务,同时也成了入侵者长驻主机的通道,入侵者可以利用一些手段得到管理员账号和密码并入侵主机.下面,我们来看看如何 ...
- 02_java之数据类型和基本运算
01变量概述 * A: 什么是变量? * a: 变量是一个内存中的小盒子(小容器),容器是什么?生活中也有很多容器,例如水杯是容器,用来装载水:你家里的大衣柜是容器,用来装载衣裤:饭盒是容器,用来装载 ...
- 判断字符串为空 为null
str:string; delphi str.IsNullOrEmpty str.IsNullOrWhiteSpace TStringHelper for delphi only,c++ no use ...
- Oracle11gR2导入导出实战之物化视图prebuilt
源实例上创建表 物化视图 oracle@localhost admin]$ sqlplus system/oracle@orcl2 SQL*Plus: Release 11.2.0.4.0 Produ ...
- MySQL学习笔记之二---引擎介绍MyISAM VS InnoDB
前言 MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一 ...
- C++防止文件重复包含
引用自:https://blog.csdn.net/xhfight/article/details/51550446 为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifnde ...