面向对象设计(OOD)思想——还是以播放器为例(ZT) s0m k<>z
wGgeK,*_
有了思想才能飞翔,缺乏灵活就象少了轮子的汽车,难以飞奔。为了更好的理解设计思想,结合一个尽可能简洁的实例来说明OOD、设计模式及重构。通过下面的代码,详细地阐述面向对象设计思想。 4ufT-&m};s
一、传统过程化设计思想 KEjMxOv1
假定我们要设计一个媒体播放器(只从软件设计的角度,不涉及硬件)。该媒体播放器目前只支持音频文件mp3和wav。按照结构化设计思想,设计出来的播放器的代码如下: {]]#q0|
public class MediaPlayer tQE<'94A
{ "2ZuI;w
private void PlayMp3() L| ]fc9W:
{ 2"EaF^?\
MessageBox.Show("Play the mp3 file."); zmFS]IOv$
} !@>q^_Gez
nCDG PzJ
private void PlayWav() D<'G\#n3I=
{ C6A!JegU
MessageBox.Show("Play the wav file."); Ze?n Q-
} ?{%"v\w
'HJ<"<
public void Play(string audioType) 0IyT(1hS
{ M44$E4a20
switch (audioType.ToLower()) "u)Le6.
{ }b^x#HC
case ("mp3"): C8%MKNPd
PlayMp3(); VNwOD-b/]
break; P6A##z
case ("wav"): hcoZ5!LvT
PlayWav(); ?Kg_bvoR
break; SN]Na<P
} LtGjHB\+
} R-tZC9
@
} y1B'_s
从传统的过程化设计思想来看,这是一段既实用又简洁的代码。 S@Aw1i p
如果,客户又提出新的要求:要播放器不仅仅播放mp3和wav文件,还要播放其他音频文件如wma、mp4等,为此我们要不断地增加相应地播放方法和修改条件语句,直止条件语句足够长。 Z|xgZG{
如果,客户感到这个媒体播放器功能太少了,只能闻其声,不能见其人,太单一。如果在听着优美音乐的同时又能看到歌唱者潇洒、英俊的舞姿那就更好了。从代码设计的角度看,他们希望媒体播放器支持视频文件了。也许你会想,不会再增加视频这方面的代码,可以,在增加视频媒体的播放方法,在修改条件判断语句,如果还有其他,还可以同样地增加、修改。到此你也许会提出,要是不修改或很少修改原来的代码就能增添其他功能该多好啊! kAs=5_?I
这样看,原来的软件设计结构似乎有点问题。事实上,随着功能的不断增加,你越来越发现这个设计非常的糟糕,因为它根本没有为未来的需求变更提供最起码的扩展。为了应接不暇的变更需求,你不得不不厌其烦地修改原来的代码,使其适应需求变化,甚至在修改代码时,由于过多的代码依赖关系弄得人焦头烂额,直止一塌糊涂。 "gt1pf~y
二、面向对象设计思想 <vt}+uMzXv
还是以设计一个媒体播放器为例,设计要求相同。不访我们换个设计思路利用面向对象设计思想(OOD)来做做看如何! xy4P_
根据OOD的思想,我们应该把mp3和wav分别看作是两个独立的对象。代码设计如下: 0xH&^Ia1B
public class MP3 Y8c,+D,Ww
{ [8&+4<
public void Play() K%UjPzPWw
{ XB]>Z)
MessageBox.Show("Play the mp3 file."); o|w
w>m
} Q]<6voyy
} @U:PXCvh
HGF&'@dn
public class WAV 3|%058bF
{ vj|#M/3>
public void Play() P1R[M|Fx
{ yp)D"w4@
MessageBox.Show("Play the wav file."); h)^|VM
} v6ei47-
} n. vrq-
:3{n(~
Public class MediaPlayer F`1J&S;C
{ 39L_O RMH
switch (audioType.ToLower()) o5:md :\
{ In8{7&iVO
case ("mp3"): 9CAu0N5<
MP3 m = new MP3(); 7rG+)kHG
m.Play(); Jp=
)L
break; Y$9x!kV
case ("wav"): "\u<\CL
WAV w = new WAV(); Y@7n>U
w.Play(); q2s=>J';
break; YF>15{H
} ^$]iUb{\
} #J t1AV
现在我们重构代码,建立统一的Play()方法,(在后面的设计中,你会发现这样改名是多么的重要!)更改媒体播放类MediaPlayer的代码。如果这样的设计代码,实质上没有多大的变化,只是对原来过程化设计思想的一种替代,并没有击中要害,亦然没有灵活性、可扩展性。 u>=\.d<
2.1单向分派技术的应用(在这里用类的多态来实现的) KwgFh#e
我们不访这样设想:既然mp3和wav都属于音频文件,都具有音频文件的共性,应该建立一个共同的AudioMedia父类。 ([#'G+MC&