步步为营,重构出模式(1)

本文通过一个控制台程序的需求,逐步引导读者理解并应用Command设计模式。从最初简单的命令处理到引入Command模式,再到进一步的重构和完善,展示了如何降低代码耦合度,提高可维护性和扩展性。

公司每年都招聘很多刚毕业的新员工,在实习的时候,每每有人向他们推荐代码大全、设计模式这两本书的时候,我都劝诫他们,代码大全是很好的书,设计模式你们看还太早,没有几万行的代码经验,你们是看不明白滴。结果还是这样的结果:看了设计模式后,只是知道概念,却不知道如何运用,貌似理解,实则不然。我就打算写一个例子,把经常会见到的模式都能体现出来,就从今天做起吧。
首先声明一下,这些文章只对新手有帮助,高手可以帮帮我改进改进,呵呵。

假设这么一个需求:一个控制台程序,需要根据用户输入的指令进行不同的处理,比如,有echo、exit,那么,我下笔就写下了下面的代码:

ContractedBlock.gif ExpandedBlockStart.gif Code
None.gifcommand = Console.ReadLine();
None.gif
if (command.IndexOf("echo"== 0)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    Console.WriteLine(command.Substring(
4, command.Length - 4));
ExpandedBlockEnd.gif}

None.gif
else if (command.IndexOf("exit"== 0)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    System.Environment.Exit(
-1);
ExpandedBlockEnd.gif}

None.gif
else
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    Console.WriteLine(
"Unknown Command:" + command);
ExpandedBlockEnd.gif}

这样的代码恰好就被一个高手看到了,高手对我说:你这样不行啊,你把对用户输入指令的接收、解析和执行统统放到一起了,耦合度太高,你需要重构,把每个不同的职责分开,不要搞得一团浆糊。
我一想,对啊,是挺乱的,怎么改呢?
对,我先把对指令的执行抽出来,单做成一个类,给它做一个方法:execute,让这个方法执行具体的动作。
过了一会儿,代码出来了,已经是如下模样了:

ContractedBlock.gif ExpandedBlockStart.gif Code
None.gifcommand = Console.ReadLine();
None.gif
if (command.IndexOf("echo"== 0)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
new EchoCommand(command.Substring(4, command.Length - 4)).execute();
ExpandedBlockEnd.gif}

None.gif
else if (command.IndexOf("exit"== 0)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
new ExitCommand().execute();
ExpandedBlockEnd.gif}

None.gif
else
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
new UnknownCommand(command).execute();
ExpandedBlockEnd.gif}

做成了三个类,EchoCommand、ExitCommand、UnknownCommand,虽然多出来三个类的代码,但是主程序看起来比以前工整多了,顺眼多了。
这个时候,高手过来看我的成果,面有喜色,说:小伙儿,不过啊,这俨然是Command模式雏形了。
啥,这就是模式了?
高手就开始说教:只是雏形而已,还有很多要做的,比如,应该对用户指令进行统一调度,三个Command类为什么不是用接口?等等等等。
我就犯愁了,这我也搞不定啊。
高手坐下来,奋笔疾书。在之前的代码基础上,加了一个接口ICommand,让三个Command类实现这个接口;加了个Processor类,对指令统一管理,最终代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
None.gifString command = "";
None.gifProcessor p 
= new Processor();
None.gifp.addCommand(
"Unknown"new UnknownCommand());
None.gifp.addCommand(
"Exit"new ExitCommand());
None.gifp.addCommand(
"Echo"new EchoCommand());
None.gif
while (true)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    command 
= Console.ReadLine();
InBlock.gif    
if (command.IndexOf("echo"== 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        p.resetRequest(
"Echo", command.Substring(4, command.Length - 4));
InBlock.gif        p.request(
"Echo");
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else if (command.IndexOf("exit"== 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        p.resetRequest(
"Exit", command);
InBlock.gif        p.request(
"Exit");
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        p.resetRequest(
"Unknown", command);
InBlock.gif        p.request(
"Unknown");
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

写完之后,高手喘了口气,说,现在的代码风格不好,你还需要重构一下。
我想,这次重构也就是把字符串定义为常量了吧。
高手很严肃地说:今天快下班就不说了,明天下午我CodeReview的时候不希望看到这么多的字符串。
啊?!这该怎么办??????

(代码:http://files.cnblogs.com/game-over/Command.rar)

转载于:https://www.cnblogs.com/game-over/archive/2008/02/23/1079047.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值