可扩展的Java应用程序开发模式
上一篇 / 下一篇 2012-08-27 10:45:44 / 个人分类:Java
摘要:这个程序最简单的版本是在主类中做每件事情,主类包含一些持有孩子姓名的数组和向量(Vector),一个另一个最简单的方法是为每个孩子创建一个对象,每个对象有一个象isFemal()这样的方法来帮助我们确定要显示的是男的还是女的。51Testing软件测试网*n5]_t$P!p3k
51Testing软件测试网g-a2{j{现在很多JAVA书籍,在介绍SWING的事件模型时,为了使JAVA初学者容易理解和上手,通常是在主类(自己的JFrame子类或JPanel)中 做所有事情:要么由主类作为监听器,在接口的方法中通过判定事件源来决定具体做何事;要么在主类中使用内隐类来实现监听器,(因为内隐类可以方便的访问主 类中的成员变量)。而很多JAVA初学者在往后的编程中也采用这种模式(至少我以前是这样的)。其实,这种做法虽然简单,却缺乏可读性、可扩展性和可维护 性。之前我看到了一篇关于这个问题的文章(来自于《JavaPro》),现整理出来与大家分享。51Testing软件测试网{9XSp bMU)pu
4Vi9FZ$mH,k^i}0 下面我将用一个简单的例子来说明如何使用模式来解决这个问题。51Testing软件测试网 GO-?lo:c}c+e
BiZ?}7oo0 现在,假设我们要编写一个使用几个单选按钮从一个长列表中选择不同分组的程序。单击Female单选按钮时,只有女孩的名字被显示;当你点击Male按钮时,程序显示男孩的名字。
c9f+| M }W;gqk051Testing软件测试网AW!|l]f!|vWF0C这个程序最简单的版本是在主类中做每件事情,主类包含一些持有孩子姓名的数组和向量(Vector),一个另一个最简单的方法是为每个孩子创建一个对 象,每个对象有一个象isFemal()这样的方法来帮助我们确定要显示的是男的还是女的。在程序中我们把每个孩子的类称为Swimmer:51Testing软件测试网 `x(O`(p8bS*`5Hs
public class Swimmer{51Testing软件测试网px'HHq_s5|g7rW private String name; ~:^A'X^,kxk0private int age; [#Dc,pkQl7} `0private String club; yDiN E['d0private boolean female; ?/r5[)h%kB0n0public Swimmer(String name,int age,String club,boolean female){ {(@Hy|w0this.name=name; (I+T'w-u!A)N0this.age=age;51Testing软件测试网_*~%U1q `&H#a;F this.club=club; ,G#GqV v(?S0Ac0this.female=female; %^AdJI_U0}51Testing软件测试网T5gNYm;N4g;P$L public boolean isFemale(){51Testing软件测试网I*ma^^+Y*a0}`+g return female; @sx`J#RG/|0} \u!J&p4C^3P3q0public String getName(){ B*z6D#BK |0return name; 2b3Z5OCl#y0}51Testing软件测试网:w&u$o]3]'MI public int getAge(){51Testing软件测试网7i.~z-T:z return age;51Testing软件测试网1|#}3\w'yJ(F*U,a } 0|'h(F&T2Ej^1Q0public String getClub(){ 7Q.F S-n!c%xNN D4Gp w0return club; `2]Z8Rv'| `@ ]Q0} B4T`L2O+Kx0} |
)p1fgOI:V.`;C0 下一步我们要做的是决定整个列表中的哪些孩子会被显示。我们可以在主用户接口类中做到这点,但是最好的是在一个叫做Swimmers的集合类中来做,这个类有一个getList()方法,它带有布尔型的参数来决定是男孩还是女孩:51Testing软件测试网~8[f]X/c&H
//get a vector of swimmers who are (female) q K] w+On2[|0public Vector getList(boolean female){ 9WZ&@#KW:{ T w_0Vector v=new Vector(); q-_L){0R8Oc*E0for(int i=0;i51Testing软件测试网:AYwK-n Swimmer swm=(Swimmer)kids.elementAt(i); K!}`E1|+b!v9H$a[6L0if(swm.isFemal()==female) v.add(swm); 6g"Q FHr0D0} UnU-S^|)kxP0return v; s8oO_cx0} |
我们又提供了一个不带参数的多态getList()方法来返回整个列表。51Testing软件测试网*P2H{.fDL _
51Testing软件测试网T+\+^"D"eO h_vG现在让我们进入程序中的第一个重要的部分,为了显示这些孩子的姓名,我们需要为三个单选按钮都添加一个事件监听器,使得每个都能显示出正确的孩子们:
r#S;J:CG!D0public void actionPerformed(ActionEvent e){51Testing软件测试网9j*FR8N:nRm//listen for button clicks and do the right thing
|5~ ^f u n.]/q0Object bj=e.getSource();
o%G.NqZ@0if(obj==female) loadFemales();51Testing软件测试网?B F+heIr
if(obj==male) loadMales();51Testing软件测试网6u H)u#odc
if(obj==both) loadBoth();
dWF-t6Z&k0}51Testing软件测试网#g?u*xA7VV
private void loadFemales(){
p n R6c]Vl0//display female swimmers51Testing软件测试网R/F jx6Y
Vector v=swimmers.getList(true);
&O1D1]_6tk0loadList(v);
(a%|IC5F0}51Testing软件测试网GI _ ]2C s
private void loadMales(){51Testing软件测试网b a| mz2A.P@
//display male swimmers
.s+QF#\i*x'}0Vector v=swimmers.getList(false);51Testing软件测试网1SA1A/}(aDl
loadList(v);
c8D_!LS0}51Testing软件测试网K/D1dnb,Q y
51Testing软件测试网*_vtadI8j
尽管这个方法在简单、小型的情况下工作得很好,但是它没有良好的可扩展性。如果你有10个按钮,扩展actionPerformed()方法来测试每个按钮和调用某些对应的操作,会使得可读性非常差。相反,我们最好在包含用户接口的类中去掉所有的判定。51Testing软件测试网Q(X;^9R*]
l6a,o.\'O0 做到这点的一个途径是使用Command模式。当我们使用这个模式的时候,需要我们创立一个Command接口:51Testing软件测试网*Z2|lxG*D
;Y~8KLn2|9_051Testing软件测试网?pQE9\qD
//the Command interface 1z"u|w/N-M)^0public interface Command{51Testing软件测试网CT`L{"?$j public void execute();51Testing软件测试网rg}J]MJ&Q*@ } |