随笔 - 22  文章 - 2 评论 - 414 trackbacks - 54

文章转载,请加入本Blog链接
软件视频教程下载

我参加的小组

我参与的团队

随笔分类

文章分类

相册

我的好友

积分与排名

  • 积分 - 79786
  • 排名 - 756

(声明:本系列所用的模式都来自GOF23中,本系列并不是讲23种经典设计模式,而是如何去使用这些模式)   

 

  一直很想写关于设计模式的具体使用的文章,可是一直没想好怎么去写,才可以通俗易懂,真正的让设计模式,应用到系统设计中.今天终于想到了,这个系列准备用实例去讲解如何使用(GOF)设计模式.

     准备用公司的人员管理系统来做这个实例,为什么选他呢?我觉得大家基本上都是公司员工,对这方面会比较熟悉.OK我们现在来定义这个系统.

客户A说:我们的系统要管理人员的工资.(为了模拟真实的开发场景,这里暂时先定义一个功能)人员分为实习员工和正式员工,他们的基本工资是不同的,工资包括基本工资和绩效工资.

 

1.分析

好,那我们现在就来分析这个系统吧,如何分析呢.大家都知道在面向对象分析中,比较难的是如何划分和定义一个类,  这里给大家介绍一个方法,"名词分析法",也就是用名词来划分你的类.举个例子:上面客户A说:"我们的系统要管理人员的工资",当然这里"我们"和"系统"这两个名词没有什么意义,就不去管它们了,我们来看接下来的"人员的工资",这里出现了人员和工资,那么我们就把他们定义成两个类Person和Salary.下面的需求:"人员分为实习员工和正式员工",那么就有实习员工和正式员工两个类,还有基本工资和绩效工资.

 

2.过滤

好,我们通过分析得到了 Person,InternshipSalary(实习员工),SttafSalary(正式员工),后两者也属于员工,那么我们只需要定义person,然后衍生出实习员工和正式员工,就可以了.

Salary,基本工资,绩效工资:由于绩效工资和公司的制度关系很密切,变化可能会很频繁,而使用设计模式的目的就是封装变化,使得代码更好的复用,所以我们要把绩效工资和Salary分开,单独封装,而基本工资就是一个数,所以直接作为Salary的一个属性就可以了.

 

3.设计

我们来看客户的话:"人员分为实习员工和正式员工,他们的基本工资是不同的,工资包括基本工资和绩效工资."

在这里Person应该包含Salary这个类,但是Person和Salary都有2种分类,而且客户很有可能再添加新的分类,那么我们如何来避免这种需求改变而带来的修改呢??

GOF23中的Bridge(桥接),就可以完成这个设计.我们来看下Bridge这种设计模式的意图:将抽象部分与他的实现部分分离,使他们都可以独立的变化.和我们的意图相符合.

 

我们知道工资中包含绩效工资,而绩效工资实际上就是一个算法,(在这里我们先不讨论怎么去评判一个人的绩效),完成多少的人给多少的绩效工资.每个人每月的绩效都不一样,可能根据很多情况发生变化.怎么来设计呢?

GOF23中的Strategy(策略):定义一系列算法,使他们可以互相替换.独立于客户代码而变换.就是他了,嘿嘿!!

 

4.类图

 

 

嘿嘿,可能大家已经看出来Bridge模式和Stratege模式很像了吧,其实他们的类图确实是一样的,从不太严格的角度来说:可以认为他们是一种实现方式,但是他们的意图不一样,Bridge更多的是类与类之间的关系,而Stratege是类与行为之间的关系,也就是说Bridge是对某一个类的一系列可变的封装,而Stratege则是对某一种可变的算法的封装。

 

2.代码:

 

绩效奖金的实现:

Code

 

 工资的实现:

Code

 

员工的实现:

 

Code

 

 调用程序:

 

Code

 

输出结果:

 

 

我们使用了两种设计模式Bridge和Strategy ,来封装了员工和工资,以及工资和绩效的变化,好了这样我们就设计完成了用户的需求,但是就上面的设计,还是有很多漏洞的,下一篇我们将继续用模式优化这些设计.

 

          下一篇:如何使用设计模式来构造系统--(2)

 

 

posted on 2008-08-07 14:52 涵舍愚人 阅读(4412) 评论(64)  编辑 收藏 网摘 所属分类: 如何使用设计模式系列

FeedBack:
#1楼 2008-08-07 15:28 Simens      
第一个抢沙发,hoho
  回复  引用  查看    
#2楼[楼主] 2008-08-07 15:29 涵舍愚人      
--引用--------------------------------------------------
Simens: 第一个抢沙发,hoho
--------------------------------------------------------
倒~~这里也流行抢沙发了~~呵呵

  回复  引用  查看    
#3楼 2008-08-07 15:41 guojing      
学习了 lz高手
  回复  引用  查看    
#4楼[楼主] 2008-08-07 15:45 涵舍愚人      

@guojing
:)--引用--------------------------------------------------
guojing: 学习了 lz高手
--------------------------------------------------------

呵呵,不是高手,只是想把自己知道的东西,分享给大家,欢迎你批评指正

  回复  引用  查看    
#5楼[楼主] 2008-08-07 15:47 涵舍愚人      
@guojing
郭靖??

  回复  引用  查看    
#6楼 2008-08-07 15:52 Roger Zhao      
很好懂,支持
  回复  引用  查看    
#7楼[楼主] 2008-08-07 15:55 涵舍愚人      
--引用--------------------------------------------------
Roger Zhao: 很好懂,支持
--------------------------------------------------------
谢谢关注

  回复  引用  查看    
#8楼 2008-08-07 15:55 水言木      
楼主工资好高啊:b

  回复  引用  查看    
#9楼[楼主] 2008-08-07 15:56 涵舍愚人      
@水言木

--引用--------------------------------------------------
水言木: 楼主工资好高啊:b

--------------------------------------------------------
呵呵,下篇文章,给你涨工资 :)

  回复  引用  查看    
#10楼 2008-08-07 16:29 荔橙伊珊雨      
楼主工资好高啊
.....

  回复  引用  查看    
#11楼[楼主] 2008-08-07 16:30 涵舍愚人      
--引用--------------------------------------------------
荔橙伊珊雨: 楼主工资好高啊
.....
--------------------------------------------------------
--引用--------------------------------------------------
涵舍愚人: @水言木



--------------------------------------------------------
呵呵,下篇文章,给你涨工资 :)
--------------------------------------------------------

  回复  引用  查看    
#12楼 2008-08-07 16:44 alisx      
在哪工作?工资这么高!
  回复  引用  查看    
#13楼[楼主] 2008-08-07 16:45 涵舍愚人      
@水言木
@荔橙伊珊雨
谢谢关注

  回复  引用  查看    
#14楼[楼主] 2008-08-07 16:46 涵舍愚人      
@alisx
呵呵,那是期望工资啊

  回复  引用  查看    
#15楼 2008-08-07 17:32 啊东hd      
非常不错,很通俗易懂。要是所有的教材都有配套这种解说那就太棒了!
期待楼主的继续。

  回复  引用  查看    
#16楼[楼主] 2008-08-07 17:34 涵舍愚人      
谢谢鼓励
  回复  引用  查看    
#17楼[楼主] 2008-08-07 17:34 涵舍愚人      
@涵舍愚人
--引用--------------------------------------------------
啊东hd: 非常不错,很通俗易懂。要是所有的教材都有配套这种解说那就太棒了!
期待楼主的继续。
--------------------------------------------------------
谢谢鼓励

  回复  引用  查看    
#18楼 2008-08-07 17:41 时间太快      
绩效奖金的实现为什么不定义一个Prize类,里面有GetBadPrize 和GetGoodPrize两个方法。
而定义成两个类呢。。???有什么好处?

  回复  引用  查看    
#19楼[楼主] 2008-08-07 17:46 涵舍愚人      
@时间太快

--引用--------------------------------------------------

时间太快: 绩效奖金的实现为什么不定义一个Prize类,里面有GetBadPrize 和GetGoodPrize两个方法。

而定义成两个类呢。。???有什么好处?

--------------------------------------------------------

如果要是有很多种绩效,定义一个类,那么你就需要去添加原有的代码,然后编译它(修改也一样).而这样只需要添加一个类.然后把它打包发布.设计上有一个原则,就是影响一个类发生变化的原因最好只有一个,还有添加胜于修改,如果封装成一个类,那么你就必须去修改它

  回复  引用  查看    
楼主是高手,我来给楼主哥哥增加些需求哈!
客户说:正式工的工资包括基本+绩效,但实习生只有补助,没有绩效。另外,客户我想获得税后工资,而不是税前的。
这个需求很实际啊,不过也是简化了一些,楼主设计下啊。

  回复  引用  查看    
#21楼[楼主] 2008-08-07 18:13 涵舍愚人      
@非主流程序员

--引用--------------------------------------------------

非主流程序员: 楼主是高手,我来给楼主哥哥增加些需求哈!

客户说:正式工的工资包括基本+绩效,但实习生只有补助,没有绩效。另外,客户我想获得税后工资,而不是税前的。

这个需求很实际啊,不过也是简化了一些,楼主设计下啊。

--------------------------------------------------------

实习生只有补助,没有绩效,这个问题因为工资这个类和绩效已经分离抽象出来了,所以你把实习生的绩效给个空,不想修改得话,给个空绩效的(建议这样做),因为客户的需求很有可能变成,实习生的也有绩效

关于税前税后的问题,缴税只是一套算法,这个算法会根据法律来变化,所以和绩效一样(实现方式一模一样),脱离出来,然后工资中加入税后的算法就可以了。这样税收的算法爱怎么变就怎么变,可能有分公司,比如上海,北京,各城市的税收不一样也没关系了,其实模式就是封装变化,根据不同的变化使用不同的模式

  回复  引用  查看    
#22楼 2008-08-07 20:00 BoyLee      
楼主工资好高啊.我的工资好少.
  回复  引用  查看    
#23楼[楼主] 2008-08-07 23:07 涵舍愚人      
--引用--------------------------------------------------
BoyLee: 楼主工资好高啊.我的工资好少.
--------------------------------------------------------
呵呵,那不是真实的

  回复  引用  查看    
#24楼 2008-08-08 03:22 Leson[未注册用户]
好文章,收藏了
  回复  引用    
#25楼 2008-08-08 03:22 8cui[未注册用户]
好东西,讲得清楚明了
  回复  引用    
#26楼 2008-08-08 08:59 横刀天笑      
实际上“名词分析法”一直被人诟病,而且灵活性也太低了,一般使用“职责驱动”的分析
  回复  引用  查看    
#27楼 2008-08-08 09:27 酱板猪      
写的蛮好的,,谢谢楼主真诚的分享
  回复  引用  查看    
#28楼 2008-08-08 09:30 DotNet菜园      
期等下文
  回复  引用  查看    
#29楼[楼主] 2008-08-08 10:27 涵舍愚人      
@Leson
谢谢关注

  回复  引用  查看    
#30楼[楼主] 2008-08-08 10:28 涵舍愚人      
@8cui
谢谢关注

  回复  引用  查看    
#31楼[楼主] 2008-08-08 10:29 涵舍愚人      
--引用--------------------------------------------------
横刀天笑: 实际上“名词分析法”一直被人诟病,而且灵活性也太低了,一般使用“职责驱动”的分析
--------------------------------------------------------
@横刀天笑
我认为两者结合会比较好,而且在这里用它,会比较直观..你觉得呢?

  回复  引用  查看    
#32楼[楼主] 2008-08-08 10:30 涵舍愚人      
@酱板猪
谢谢.欢迎常来

  回复  引用  查看    
#33楼[楼主] 2008-08-08 10:32 涵舍愚人      
@DotNet菜园
谢谢关注

  回复  引用  查看    
#34楼 2008-08-08 11:25 yatasoft      
俄,文章很好,支持支持啦。
这里面用依赖倒置原则——针对对接口编程,就可以推出这个解决方案,人和工资均是变化的,分别抽象出接口独立变化,这也符合解耦的原则,
但是我现在还不知道”Bridge设计模式的意图:将抽象部分与他的实现部分分离“,在这个项目中谁是抽象部分,谁是实现部分。
希望您指导谢谢

  回复  引用  查看    
#35楼[楼主] 2008-08-08 12:48 涵舍愚人      
@yatasoft
--引用--------------------------------------------------
yatasoft: 俄,文章很好,支持支持啦。
这里面用依赖倒置原则——针对对接口编程,就可以推出这个解决方案,人和工资均是变化的,分别抽象出接口独立变化,这也符合解耦的原则,
但是我现在还不知道”Bridge设计模式的意图:将抽象部分与他的实现部分分离“,在这个项目中谁是抽象部分,谁是实现部分。
希望您指导谢谢
--------------------------------------------------------
人员包含了工资,所以工资是需要抽象出来,独立变化的

  回复  引用  查看    
#36楼 2008-08-08 14:37 阿aaa[未注册用户]
好东西,收下了,谢谢楼主
  回复  引用    
不错~~UP
  回复  引用    
#38楼 2008-08-08 14:41 Kill[未注册用户]
--引用--------------------------------------------------
奥运来了: 不错~~UP
--------------------------------------------------------

  回复  引用    
--引用--------------------------------------------------
阿aaa: 好东西,收下了,谢谢楼主
--------------------------------------------------------

  回复  引用    
#40楼 2008-08-08 15:26 BBLINK[未注册用户]
期待下文
  回复  引用    
#41楼[楼主] 2008-08-09 23:01 涵舍愚人      
@阿aaa

谢谢,欢迎常来。

  回复  引用  查看    
#42楼[楼主] 2008-08-09 23:02 涵舍愚人      
@奥运来了

谢谢关注

  回复  引用  查看    
#43楼[楼主] 2008-08-09 23:11 涵舍愚人      
@Kill
谢谢关注

  回复  引用  查看    
#44楼[楼主] 2008-08-09 23:11 涵舍愚人      
@God is Boy
谢谢关注

  回复  引用  查看    
#45楼[楼主] 2008-08-09 23:11 涵舍愚人      
@BBLINK
谢谢关注

  回复  引用  查看    
你举的例子好象不是很好,
抽象和实现不能自由的组合,违背bridage的用意
Internship 只能和 InternshipSalary 组合
Sttaf 只能和 SttafSalary 组合

交叉的组合是没意义的,
比如:Internship 和 SttafSalary 组合....

  回复  引用    
#47楼[楼主] 2008-08-12 14:41 涵舍愚人      
--引用--------------------------------------------------
wangyongahz88: 你举的例子好象不是很好,
抽象和实现不能自由的组合,违背bridage的用意
Internship 只能和 InternshipSalary 组合
Sttaf 只能和 SttafSalary 组合

交叉的组合是没意义的,
比如:Internship 和 SttafSalary 组合....
--------------------------------------------------------
你完全可以去这样组合,Bridge就是让抽象和实现分离,既然抽象出来,就可以去那样组合。只是我起的类名让你有这样的感觉,这样起类名,主要是为了清晰和更容易理解。

  回复  引用  查看    
不错,学习了,
  回复  引用  查看    
#49楼[楼主] 2008-08-15 11:05 涵舍愚人      
--引用--------------------------------------------------
共同学习,共同进步: 不错,学习了,
--------------------------------------------------------
谢谢关注

  回复  引用  查看    
#50楼 2008-08-15 14:25 涤生      
--引用--------------------------------------------------
wangyongahz88: 你举的例子好象不是很好,
抽象和实现不能自由的组合,违背bridage的用意
Internship 只能和 InternshipSalary 组合
Sttaf 只能和 SttafSalary 组合

交叉的组合是没意义的,
比如:Internship 和 SttafSalary 组合....
--------------------------------------------------------
你完全可以去这样组合,Bridge就是让抽象和实现分离,既然抽象出来,就可以去那样组合。只是我起的类名让你有这样的感觉,这样起类名,主要是为了清晰和更容易理解。

我认为正是因为你类名称的关系,使得你这个Bridge模式没有什么说服力。既然是想说明Bridge模式,则要体现出Bridge达到降低类的多纬度变化。所以为了更好的表现你的Bridge模式,建议重新构造一下场景和类的名称。

By the way: The article's objective is perfect. Thanks for your work.

  回复  引用  查看    
#51楼[楼主] 2008-08-15 14:59 涵舍愚人      
@涤生
我也想过重新去构造一下类名,但是又怕类名的不确定性,给新手带来困惑..

  回复  引用  查看    
#52楼[楼主] 2008-08-15 15:36 涵舍愚人      
--引用--------------------------------------------------
DotNet菜园: 期等下文
--------------------------------------------------------
xiexie

  回复  引用  查看    
#53楼 2008-08-25 15:46 Sabre      
弱弱的问一下:
_salaryNum = 3000;//实习者的工资基数
return _salaryNum + _salaryprize.GetPrize(this);
这里为什么不用属性访问呢?

  回复  引用  查看    
#54楼[楼主] 2008-08-27 10:56 涵舍愚人      
--引用--------------------------------------------------

Sabre: 弱弱的问一下:

_salaryNum = 3000;//实习者的工资基数

return _salaryNum + _salaryprize.GetPrize(this);

这里为什么不用属性访问呢?

--------------------------------------------------------

也可以,看你是否带参数了

  回复  引用  查看    
#55楼 2008-08-28 14:35 clefoo      
@涵舍愚人
你的联系方式多少啊。。能不能做朋友啊。。。
喜欢你的设计模式文章,通俗易懂,。。最好有源码可以下载啊。。要不又要复制代码去学习了

  回复  引用  查看    
#56楼 2008-08-28 14:37 clefoo      
请务必答复啊
  回复  引用  查看    
#57楼[楼主] 2008-08-29 11:22 涵舍愚人      
--引用--------------------------------------------------
clefoo: @涵舍愚人
你的联系方式多少啊。。能不能做朋友啊。。。
喜欢你的设计模式文章,通俗易懂,。。最好有源码可以下载啊。。要不又要复制代码去学习了
--------------------------------------------------------
原代码我写完这个系列一起上传!我的Email:xugao918@163.com

  回复  引用  查看    
#58楼[楼主] 2008-08-29 11:23 涵舍愚人      
--引用--------------------------------------------------
clefoo: 请务必答复啊
--------------------------------------------------------
答复了...MSN:xulei-kevin@hotmail.com

  回复  引用  查看    
#59楼 2008-09-05 10:06 JustForKim      
楼主你好。

对于这样一个场景使用Bridge感觉不太对,将抽象部分与他的实现部分分离,使他们都可以独立的变化。这个示例代码里面,Person类的变化是public abstract double GetShouldpaid(IPrize prize);而salary类的变化又是public abstract double GetShouldpaid(); 这两个变化导致重叠,场景理解起来已经混淆了。

  回复  引用  查看    
#60楼[楼主] 2008-09-05 10:31 涵舍愚人      
--引用--------------------------------------------------
JustForKim: 楼主你好。
<br>
对于这样一个场景使用Bridge感觉不太对,将抽象部分与他的实现部分分离,使他们都可以独立的变化。这个示例代码里面,Person类的变化是public abstract double GetShouldpaid(IPrize prize);而salary类的变化又是public abstract double GetShouldpaid(); 这两个变化导致重叠,场景理解起来已经混淆了。
--------------------------------------------------------
Person的变化是应付多少工资,而工资的变化是他自己!!所以方法名的重叠并没有什么太大的影响,关键你要知道Person和工资不是属于一个类的,他们是独立的,也许实习的没有工资...那么他还是属于Person类,对吗?

  回复  引用  查看    
#61楼 2008-09-05 10:49 JustForKim      
Person的变化按场景来说,应该是员工类型,需求里面已经包括了两种人员类型了,如再加多一种也是按照员工类型这一变化维度进行实现的,Person类应该包含员工类型以及salary类,而求某人的薪水时应该使用Person.salary.GetShouldpaid()这样来取的。如Person 既包括salary类,又包括GetShouldpaid(),从类的成员划分来看是否重叠。个人理解,请解惑:)
  回复  引用  查看    
#62楼 2008-09-08 22:16 swfczm      
楼主写的真不错!!!
  回复  引用  查看    
#63楼[楼主] 2008-09-10 13:23 涵舍愚人      
--引用--------------------------------------------------
JustForKim: Person的变化按场景来说,应该是员工类型,需求里面已经包括了两种人员类型了,如再加多一种也是按照员工类型这一变化维度进行实现的,Person类应该包含员工类型以及salary类,而求某人的薪水时应该使用Person.salary.GetShouldpaid()这样来取的。如Person 既包括salary类,又包括GetShouldpaid(),从类的成员划分来看是否重叠。个人理解,请解惑:)
--------------------------------------------------------
这样做只是起到一个Facade,让客户代码写起来更简单

  回复  引用  查看    
#64楼[楼主] 2008-09-10 13:29 涵舍愚人      
--引用--------------------------------------------------
swfczm: 楼主写的真不错!!!
--------------------------------------------------------
谢谢关注

  回复  引用  查看    
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1262885




相关文章:

相关链接: