设计模式六大原则----------开闭原则

设计模式总览


遵循开闭原则设计出的模块具有两个主要特征:
(1)对于扩展是开放的(Open for extension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。
(2)对于修改是关闭的(Closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。

注意:这里的修改指的是因功能拓展而引起的修改!!!!


实现方法:抽象出所有变化的部分。


EVP要求在做系统设计的时候,对系统所有可能发生的变化部分进行评估和分类,每一个可变的因素都单独进行封装。


举例分析:

小狗在不同状态(心情)下,会有不同的移动方式(狗也是有情绪滴撒)。比如:在开心的时候,跳着跑;伤心的时候低着头跑;害怕的时候,夹着尾巴跑。

版本一:

if(state == "开心")
    跳着跑;
else if(state == "伤心")
	低着头跑
else if(state == "害怕")
	夹着尾巴跑;
else
	正常跑
假如这段代码是作为sdk发出去的,不允许对其随便修改!然而现在有新需求,要求在愤怒的时候,咬牙跑。问题来了,打破了开闭原则!

版本二:

IMove __move
void setMoveStage(IMove move)
{
	__move = move
}

void move()
{
	__move()
}

client:
if(dog.state == "开心")
	dog.setMoveStage(跳着跑)
else if(dog.state == "伤心")
	dog.setMoveStage(低着头跑)
else if(dog.state == "害怕")
	dog.setMoveStage(夹着尾巴跑;)
else if(dog.state == "愤怒")
	dog.setMoveStage(咬牙跑)
else
	dog.setMoveStage(正常跑)
将变化的部分抽象出来,不变的部分放在dog中,现在再进行拓展,就不用修改dog的类了,只需要修改客户端。

版本二的方法已经解决了开闭原则问题,并且它就是一个简单的策略模式,但这样的代码太丑了,如果你有强迫症,可以再进行修改

版本三

void registMove(State state, IMove move)
{
	dictionary[state] = move;
}

void setState(State state)
{
	mState = state;
	mMove = dictionary[state];
}
client:
dog.setState("开心")

这样,只需要在开始时,注册好所有的移动方式,然后在每次改变心情时,自动的修改了相应的move方式。如果要进行拓展,添加新的移动方式,也只需要修改客户端启动时,注册move的地方。


下面是个计算器的例子:

以简单的计算器程序来说。假如让你设计一个支持+、-、*、%的计算器,那么在设计的时候肯定会想到以后会不会有拓展?拓展到支持平方、幂运算、开方等运算?那么,这里的运算功能就是一个可变部分,所以要对这个可变部分进行抽象。如图:


当要拓展新的运算时,只需要根据操作数的个数添加相应的实体类就行了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值