<marquee width=358>欢迎来到月影社区,希望这里可以成为您美丽的梦幻花园,如果你觉得这里好请分享给您的朋友!- wf66.com</marquee> 将月影社区设置为您的首页将月影社区地址加入到您的收藏栏
月影社区时尚音乐音乐查询IP手机许愿之瓶最新更新文件加密访客留言爱音乐
欢迎您,首页 >> 信息中心 >> 可扩展的Java应用程序开发模式

请输入您关键字:


可扩展的Java应用程序开发模式

推荐查看本文HTML版本

现在很多JAVA书籍,在介绍SWING的事件模型时,为了使JAVA初学者容易理解和上手,通常是在主类(自己的JFrame子类或JPanel)中做所有事情:要么由主类作为监听器,在接口的方法中通过判定事件源来决定具体做何事;要么在主类中使用内隐类来实现监听器,(因为内隐类可以方便的访问主类中的成员变量)。而很多JAVA初学者在往后的编程中也采用这种模式(至少我以前是这样的)。其实,这种做法虽然简单,却缺乏可读性、可扩展性和可维护性。之前我看到了一篇关于这个问题的文章(来自于《JavaPro》),现整理出来与大家分享。

下面我将用一个简单的例子来说明如何使用模式来解决这个问题。

现在,假设我们要编写一个使用几个单选按钮从一个长列表中选择不同分组的程序,就象下图中看到的。单击Female单选按钮时,只有女孩的名字被显示;当你点击Male按钮时,程序显示男孩的名字。


这个程序最简单的版本是在主类中做每件事情,主类包含一些持有孩子姓名的数组和向量(Vector),一个另一个最简单的方法是为每个孩子创建一个对象,每个对象有一个象isFemal()这样的方法来帮助我们确定要显示的是男的还是女的。在程序中我们把每个孩子的类称为Swimmer:


public class Swimmer{
 private String name;
 private int age;
 private String club;
 private boolean female;

 public Swimmer(String name,int age,String club,boolean female){
this.name=name;
this.age=age;
this.club=club;
this.female=female;
 }

 public boolean isFemale(){
return female;
 }

 public String getName(){
return name;
 }

 public int getAge(){
return age;
 }

 public String getClub(){
return club;
 }
}

下一步我们要做的是决定整个列表中的哪些孩子会被显示。我们可以在主用户接口类中做到这点,但是最好的是在一个叫做Swimmers的集合类中来做,这个类有一个getList()方法,它带有布尔型的参数来决定是男孩还是女孩:


//get a vector of swimmers who are (female)
public Vector getList(boolean female){
 Vector v=new Vector();
 for(int i=0;iSwimmer swm=(Swimmer)kids.elementAt(i);
if(swm.isFemal()==female) v.add(swm);
 }
 return v;
}

我们又提供了一个不带参数的多态getList()方法来返回整个列表。

现在让我们进入程序中的第一个重要的部分,为了显示这些孩子的姓名,我们需要为三个单选按钮都添加一个事件监听器,使得每个都能显示出正确的孩子们:


public void actionPerformed(ActionEvent e){
 //listen for button clicks and do the right thing
 Object obj=e.getSource();
 if(obj==female) loadFemales();
 if(obj==male) loadMales();
 if(obj==both) loadBoth();
}

private void loadFemales(){
 //display female swimmers
 Vector v=swimmers.getList(true);
 loadList(v);
}

private void loadMales(){
 //display male swimmers
 Vector v=swimmers.getList(false);
 loadList(v);
}

尽管这个方法在简单、小型的情况下工作得很好,但是它没有良好的可扩展性。如果你有10个按钮,扩展actionPerformed()方法来测试每个按钮和调用某些对应的操作,会使得可读性非常差。相反,我们最好在包含用户接口的类中去掉所有的判定。

做到这点的一个途径是使用Command模式。当我们使用这个模式的时候,需要我们创立一个Command接口:


//the Command interface
public interface Command{
 public void execute();
}

我们将三个单选按钮扩展成特定的带有Command接口的类,我们就可以把对命令的执行从JFrame类转移到每个按钮的类。同时,我们创建一个叫做SexButton的基类,并将ActionListener代码移到基类中,这样就不需要分别在每个按钮中添加事件监听器:


//abstract radio button class
public abstract class SexButton
extends JRadioButton implements Command{
 protected Swimmers simmers;
 //JawList is a subclass of JScrollPane contained a JList;
 protected JawList kidList;

 public SexButton(String title,Swimmers sw,
 JawList klist,ActionListener al){
super(title);
swimmers=sw;
kidList=klist;
addActionListener(al);
 }

 //abstract execute method
 public abstract void execute();
}

注意这个类必须被扩展以使得它有用,因为我们没有具体化execute()方法。这个基本的抽象按钮类只是我们从中导出的具体类的一个模板,这实际也是模板设计模式的一个简单例子。


//radio button to select female swimmers
public class FemaleButton extends SexButton{
 public execute(){
Vector v=swimmers.getList(true);
loadList(v);
 }

 private void loadList(Vector v){
kidList.clear();
for(int i=0;i Swimmer swm=(Swimmer)v.elementAt(i);
 kidList.add(swm.getName());
}
 }
}

现在,来看一下我们完成的工作。所有的按钮都成为了Command按钮了,actionPerformed()方法也简化成下面这样简单的方法:


public void actionPerformed(ActionEvent e){
 Command cmd=(Command)e.getSource();
 cmd.execute();
}

正如你看到的,这更加简单而且完全是可扩展的。
 但我们还有要做的事情。现在我们写了三个单选按钮类,它们知道如何载入一个列表框。在我们匆忙地想要从主类之外得到消息时,我们要求每个按钮都知道列表框。如果我们想要改成一个不同的显示方式,就必须修改这三个类。

如果我们在按钮和列表之间创建一个mediator(调停者)类就会好得多,因为它们彼此不需要知道对方。Mediator(调停者)设计模式能够做到这一点。当一个按钮被点击时,我们创建一个调停者类载入列表。这样所有按钮只知道调停者,哪个列表被载入也只有调停者才知道,当我们想要改成一个不同的显示方式就只需修改Mediator:


public class Mediator{
 private JawList kidList;

 public Mediator(JawList klist){
kidList=klist;
 }

 public void loadList(Vector v){
kidList.clear();
for(int i=0;i Swimmer sw=(Swimmer)v.elementAt(i);
 kidList.add(sw.getName());
}
 }
}

这样我们的基类变成这样:


public abstract class SexButton
extends JRadioButton implements Command{
 protected Swimmers swimmers;
 protected Mediator med;

 public SexButton(String title,Swimmers sw,Mediator md,ActionListener al){
super(title);
swimmers=sw;[月影社区 http://wf66.com/]
med=md;
addActionListener(al);
 }

 public abstract void execute();
}

而FemalButton则变成这样:


public class FemaleButton extends SexButton{
 //use the mediator to load the list
 public void execute(){
Vector v=swimmers.getList(true);
med.loadList(v);
 }
}

你看,我们使用Mediator来分离按钮和列表,使它们互相不知道对方。

除了可以使用命令、调停者、模板模式改进这个不到100行的Java代码的简单程序外,还可以使用观察者(Observer)模式。这个程序使用JListData将数据传给列表并从列表中获得数据,并用LawList观察JListData的变化。


public class JListData extends AbstractListModel{
 private Vector data;

 public JListData(){
data=new Vector();
 }

 public int getSize(){
return data.size();
 }

 public Object getElementAt(int index){
return data.elementAt(index);
 }

 public void addElement(String s){
data.addElement(s);
fireIntervalAdded(this,data.size()-1,data.size());
 }

 public void removeElement(String s){
data.removeElement(s);
fireIntervalRemoved(this,0,data.size());
 }

 public void clear(){
int size=data.size();
data.clear();
fireIntervalRemoved(this,0,size);
 }
}

public class JawList extends JScrollPane{
 private JList listwindow;
 private JListData listContents;

 public JawList(){
listContents=new JListData();
listwindow=new JList(listContents);
getViewport().add(listwindow);
 }

 public void add(String s){
listContents.addElement(s);
 }

 public void remove(String s){
listCotents.removeElements(s);
 }

 public void clear(){
listContents.clear();
 }
}


可扩展的Java应用程序开发模式 2006-9-20
转到本主题第:[ 1 ]
相关评论

暂无评论

总计0页 [ ]上一页 下一页
发表评论(揪错)
呢称: * 您尚未登陆,请登录
来自: *
内容:
 

(为防止非法信息,您的言论提交后需要审核才能正常显示)

文学
精品文萃 情感天地 言情小说
网络小说 玄幻小说 悬疑恐怖
武侠小说 古典品谈 外国名著
儿童文学 会员原创 学习园地
杂谈其它
娱乐
爆笑网文 星座占卜 影音动漫
娱乐新闻 影视剧情
诗词
青竹诗歌 个人诗集 宋词雅赏
全唐诗录
新闻
国际新闻 国内新闻 科技新闻
体育新闻
图片
图文专区 艺术长廊 桌面壁纸
精品素材 像素图片
漫画
单幅漫画 爆笑四格 连环漫画
电脑
电脑入门 图形图像 编程开发
游戏
我爱Q宠 最新攻略 最新秘籍
游戏新闻 技巧心得
经济
帕格节电 财经资讯 股市证券
生活
百科知识 外语学院 潮流时尚
健康医疗 宠物花卉 汽车地带
行走天下
美食
面食甜点 家常菜品 药膳食疗
美食天下 烹饪技巧 松辽风味
燕京风味 巴蜀风味 滇黔风味
赣江风味 徽皖风味 闽台风味
齐鲁风味 中州风味 岭南风味
荆楚风味 三晋风味 淞沪风味
苏扬风味 潇湘风味 钱塘风味
民族风味 素斋仿荤
营销
管理杂谈 谈经论道 培训激励
经营战略 职场生涯 公关交际
关于我们版权声明本站导航友情连结作品演示 TOP↑
本论坛言论纯属发表者个人意见,与£月影社区£立场无关。 皖ICP备16024038号-1
禁止发布任何色情/政治/反动相关信息让我们共同来营造一个属于我们的梦幻家园
Copyright ©2001-2006 MoonShadow. All rights reserved.  Version 4.0  Licence 2006.4.2
建站天数:7211天 本站基于ASP+JS构建,完全自主开发,版权归属月影社区 管理员QQ:23165062 Time:31ms