设计模式实战MVC模式.docx
- 文档编号:5871489
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:9
- 大小:57.03KB
设计模式实战MVC模式.docx
《设计模式实战MVC模式.docx》由会员分享,可在线阅读,更多相关《设计模式实战MVC模式.docx(9页珍藏版)》请在冰豆网上搜索。
设计模式实战MVC模式
设计模式:
实战MVC模式
内容:
1.MVC
2.Observer接口
3.模型Model
4.视图View
5.控制器Controller
6.运行程序
MVC
“模型-视图-控制器(Model-View-Controller,MVC)结构是为那些需要为同样的数据提供多个视图的应用程序而设计的,它很好的实现了数据层与表示层的分离。
例如下图中的例子:
我们看到,图中的几组数据以不同的形式(View)表现出来,一个是表格样式,一个是图形样式。
MVC把这种应用程序分为三种对象类型:
模型:
维护数据并提供数据访问方法。
视图:
给制模型的部分数据或所有数据的可视图。
控制器:
处理事件.
以下是典型的MVC通信方式,
事件由控制器来处理,控制器接收用户事件,并根据事件的类型来改变模型。
视图事先会在模型中登记,当模型数据发生改变时,马上通知已向此模型登记的每个视图。
视图从模取得最新的数据并刷新自己.
要实现MVC,最重要的一个环节是使用DesignPattern中的Observer模式。
Observer模式允许某个对象在所观察的对象发生修改时通知多个观察者(Observer).
下面我们就以实例来讲解如何用Obserer模式实现MVC的程序结构。
在我的例子中,我要实现一个学生年龄显示的例子。
分别用清单和图形的方式显示每个学生的年龄。
当年龄改变时,自动更新显示。
Observer接口
为了实现观察的对象发生修改时通知多个观察者,通常要在被观察者与观察者之间有一个小的接口,如下:
/*file:
Observer.java*/
publicinterfaceObserver
{
publicvoiddataUpdate(Modelmodel);
}
这个接口中有一个dataUpdate(Modelmodel)方法,只要实现了这个接口对象,就成了一个观察者。
模型Model
再来建立一个数据模型。
在我的例子中,先建立了一个数据对象:
/*file:
Data.java*/
publicclassData
{
publicintvalue; //学生年龄值
publicStringname; //学生名
}
现在来建立一个Model:
/*file:
Model.java*/
importjava.util.*;
publicclassModel
{
ArrayListdata=newArrayList();
ArrayListobserver=newArrayList();
publicModel()
{ super();
}
publicModel(int[]value,String[]name)
{
for(inti=0;i { addData(value[i],name[i]); } } publicModel(Data[]data) { for(inti=0;i { addData(data[i]); } } publicvoidaddData(intvalue,Stringname) { Datadata=newData(); data.value=value; data.name=name; this.data.add(data); } publicvoidaddData(Datadata) { this.data.add(data); } publicDatagetData(intidx) { return(Data)(data.get(idx)); } publicintsize() { returndata.size(); } //用来向模型中登记观察者. publicvoidregisterObserver(Observero) { observer.add(o); } publicvoidremoveObserver(Observero) { observer.remove(o); } //当数据改变时,由Controller调用此方法,通知各个Observer,刷新视图. publicvoidchangeModel(Modelmodel) { data.clear(); for(inti=0;i { this.addData(model.getData(i)); } dataUpdate(); } privatevoiddataUpdate() { for(Iteratori=observer.iterator();i.hasNext();) { Observero=(Observer)(i.next()); o.dataUpdate(this); } } } 这个模型提供各种数据访问的方法。 并提供一个changeModel(Modelmodel)方法供Controller访问。 还提供一个registerObserver(Observero)方法,用来向Model中登记观察者Observer。 视图View 我们要实现一个清单显示样式的视图View1和一个图形方式显示的视图View2,并让它们实现Observer接口,以便当Model数据改变时,自动刷新自己. /*file: View1.java*/ importjavax.swing.*; importjava.awt.*; importjavax.swing.border.*; publicclassView1extendsJPanelimplementsObserver { Modelmodel; publicView1() { } publicView1(Modelmodel) { try { this.model=model; jbInit(); } catch(Exceptione) { e.printStackTrace(); } } privatevoidjbInit()throwsException { this.setBackground(Color.white); this.setBorder(newTitledBorder(BorderFactory.createLineBorder(Color.black,1),View1)); } publicvoidpaintComponent(Graphicsg) { super.paintComponent(g); if(model==null)return; intx=20,y=50; inth=g.getFontMetrics().getHeight(); for(inti=0;i { Datadata=model.getData(i); g.drawString(data.name,x,y); y+=h; g.drawString(String.valueOf(data.value),x,y); y+=h; } } //当模型数据发生改变时,会自动调用此方法来刷新图形 publicvoiddataUpdate(Modelmodel) { /**@todo: ImplementthisObservermethod*/ this.model=model; repaint(); } } /*file: View2.java*/ importjavax.swing.*; importjava.awt.*; importjavax.swing.border.*; publicclassView2extendsJPanelimplementsObserver { Modelmodel; publicView2() { } publicView2(Modelmodel) { try { this.model=model; jbInit(); } catch(Exceptione) { e.printStackTrace(); } } privatevoidjbInit()throwsException { this.setBackground(Color.white); this.setBorder(newTitledBorder(BorderFactory.createLineBorder(Color.black,1),View1)); } publicvoidpaintComponent(Graphicsg) { super.paintComponent(g); if(model==null)return; intx=20,y=50; inth=g.getFontMetrics().getHeight(); intwidth=this.getWidth(); intheight=this.getHeight(); intsy=height/model.size(); intsx=width/2; for(inti=0;i { Datadata=model.getData(i); intvalue=data.value; intdx=3; intr=3; Colorc=newColor((int)(255*Math.random()),(int)(255*Math.random()),(int)(255*Math.random())); intcx=sx; intcy=y+i*sy; for(intj=0;j { g.setColor(c); g.drawOval(cx,cy,r,r); r+=dx; } g.drawString(data.name,25,cy); } } //当模型数据发生改变时,会自动调用此方法来刷新图形 publicvoiddataUpdate(Modelmodel) { /**@todo: ImplementthisObservermethod*/ this.model=model; repaint(); } } 控制器Controller 好了,MVC中的Model,Observer都建立好了,我们最后来做一个Controller: importjava.awt.*; importjavax.swing.*; importjavax.swing.border.*; importjava.awt.event.*; publicclassControllerextendsJFrame { Modelmodel= newModel(); View1view1=newView1(model); View2view2=newView2(model); JScrollPanejScrollPane1=newJScrollPane(); JButtonjButton1=newJButton(); JTextFieldjTextField1=newJTextField(); JTextFieldjTextField2=newJTextField(); JLabeljLabel1=newJLabel(); JLabeljLabel2=newJLabel(); JLabeljLabel3=newJLabel(); publicController() { try { jbInit(); } catch(Exceptione) { e.printStackTrace(); } } privatevoidjbInit()throwsException { Data[]data=newData[2]; data[0]=newData(); data[1]=newData(); data[0].name=Ted; data[0].value=20; data[1].name=Joy; data[1].value=14; model.addData(data[0]); model.addData(data[1]); //注意下面两行: 向模型中登记它的观察者View1和View2. model.registerObserver(view1); model.registerObserver(view2); this.getContentPane().setLayout(null); jScrollPane1.setBounds(newRectangle(0,0,3,3)); jButton1.setBounds(newRectangle(309,259,101,27)); jButton1.setText(Update); jButton1.addActionListener(newjava.awt.event.ActionListener() { publicvoidactionPerformed(ActionEvente) { jButton1_actionPerformed(e); } }); jTextField1.setText(20); jTextField1.setBounds(newRectangle(80,254,52,30)); jTextField2.setText(14); jTextField2.setBounds(newRectangle(178,255,50,31)); jLabel1.setText(Age: ); jLabel1.setBounds(newRectangle(41,226,47,23)); jLabel2.setText(Ted); jLabel2.setBounds(newRectangle(42,252,35,33)); jLabel3.setText(Joy); jLabel3.setBounds(newRectangle(144,255,31,31)); view1.setBounds(newRectangle(7,5,225,208)); view2.setBounds(newRectangle(234,4,219,209)); this.getContentPane().add(jScrollPane1,null); this.getContentPane().add(jTextField2,null); this.getContentPane().add(jTextField1,null); this.getContentPane().add(jLabel2,null); this.getContentPane().add(jLabel3,null); this.getContentPane().add(jLabel1,null); this.getContentPane().add(jButton1,null); this.getContentPane().add(view1,null); this.getContentPane().add(view2,null); } //按下Update按钮,通知Model数据发生改变. voidjButton1_actionPerformed(ActionEvente) { Data[]data=newData[2]; data[0]=newData(); data[1]=newData(); data[0].name=jLabel1.getText(); data[0].value=Integer.parseInt(jTextField1.getText()); data[1].name=jLabel2.getText(); data[1].value=Integer.parseInt(jTextField2.getText()); Modelm=newModel(data); this.model.changeModel(m); } publicstaticvoidmain(String[]args) { Controllerc=newController(); c.setSize(475,310); c.setVisible(true); } } 运行程序 各位可以将这些代码各自存为相应的源文件,执行以下命令编译 javacController.java 运行 javaController.class 就可以看到程序执行的效果, 你可以试着改变两个学生的年龄,按一下Update按钮,相应的视图就更新了。 怎么样,体验到了MVC结构给程序带来的方便性了吧? ;) 大家如果运行程序有任何问题,或需编译好的程序,可与我联络。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 设计 模式 实战 MVC