MVC风格

MVC风格

点击了解更多软件体系结构风格

§模型-视图-控制器风格常被简称为MVC风格

§组件:模型、视图、控制器

§连接件:显式调用、隐式调用、其他机制(例如:Http协议)

工作机制:

Model:

§模型的职责

–负责数据存取

–负责业务逻辑实现

–负责数据验证

§模型:模型是应用程序的核心。它封装内核数据与状态,对模型的修改将扩散到所有视图中。所有需要从模型获取信息的对象都必须注册为模型的视图。

§在事件驱动系统,当信息发生改变,模型通知观察者(observers) (通常是视图),从而引起视图反应。

View:

§视图的职责:

–获取用户输入

–向controller发送处理请求

–接收来自Controller的反馈

–将model的处理结果显示给用户

§一个model可能有多个View

Controller:

§控制器职责:

–接收来自客户的请求

–调用model执行

–调用View显示执行结果

§控制器:控制器是提供给用户进行操作的接口。每个视图与一个控制器组件相关联。控制器接收用户的输入,通常是鼠标移动、键盘输入等。输入事件翻译成服务请求,送到模型或视图。用户只通过控制器与系统交互。

§两个主要分离:

–模型与界面分离

–控制器与视图分离

§优点:

–将各方面问题分解开来考虑,简化了系统设计,保证了系统的可扩展性。

–改变界面不影响应用程序的功能内核,使得系统易于演化开发,可维护性好。

–同一信息可以有不同的展现方式。

–业务逻辑更易测试

程序:

模型类CarModel封装二手车软件的业务逻辑部分,包括核心数据以及tell()方法(将状态的改变通知视图类)

import java.io.*;

import java.net.URL;

import java.net.URI;

import javax.swing.*;

importjava.util.*;

public classCarModel{

private String[] carNameList;

privateURL imgURL;

privateURL carFileUrl;

privateImageIcon imgIcon;

private String carSelected;

private String bitPrice;

static final String CARFILES ="CarFiles/";

static final String CARIMAGES ="CarImages/";

public CarModel(){

carNameList=new String[200];

}

public void setCarList(String[] cars){

carNameList = cars;

}

public String[] getCarList(){

return  carNameList;

}

public void setSelectedCar(String sCar){

carSelected = sCar;

}

publicString getSelectedCar(){

return carSelected;

}

publicvoid setBitPrice(String bPrice){

bitPrice = "";

bitPrice = bitPrice + bPrice;

}

public String getBitPrice(){

return bitPrice;

}

public void setupImageIcon(){

String iconStr = CARIMAGES + carSelected+".jpg";

imgIcon = createImageIcon(iconStr);

}

public ImageIcon getImageIcon(){

return imgIcon;

}

public void setCarFileURL(){

try{

String fileURLStr = CARFILES + carSelected+ ".html";

URI uri = (new File(fileURLStr)).toURI();

carFileUrl= uri.toURL();

}

catch (IOException e){

e.printStackTrace();

}

}

public URL getCarFileURL(){

return carFileUrl;

}

protected ImageIcon createImageIcon(Stringpath){

imgURL = getClass().getResource(path);

if (imgURL != null) {

return new ImageIcon(imgURL);

} else {

System.err.println("Couldn‘tfind file: " + path);

return null;

}

}

public void tell(View view){

view.update();

}

} // End ofclass

视图类CararGUIView和CarBitView为图形界面类,在update()方法中自动调用CarModel类的有关信息,并显示在图形界面上。

public interface View{

publicabstract void update();

}

import java.awt.*;

import java.util.*;

import javax.swing.*;

import java.io.*;

import java.net.URL;

import java.awt.event.*;

import com.sun.java.swing.plaf.windows.*;

public classCarGUIView extends JFrame implements View{

private JEditorPane editorPane;

private JScrollPane imagePane;

private JScrollPane textPane;

private JSplitPane splitPane;

private JLabel imgLabel;

private CarModel model;

public CarGUIView(CarModel cmodel){

super("Car information- Observer1");

model = cmodel;

buildUpScrollGUI();

}

private void buildUpScrollGUI(){

imgLabel = new JLabel();

imgLabel.setBackground(Color.green);

imgLabel.setMinimumSize(new Dimension(250, 200));

editorPane = new JEditorPane();

editorPane.setEditable(false);

imagePane = new JScrollPane(imgLabel);

imagePane.getViewport().setBackground(Color.green);

textPane = new JScrollPane(editorPane);

textPane.setMinimumSize(new Dimension(250, 200));

splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);

splitPane.setLeftComponent(imagePane);

splitPane.setRightComponent(textPane);

Dimension minimumSize = new Dimension(130, 100);

imagePane.setMinimumSize(minimumSize);

textPane.setMinimumSize(new Dimension(100, 100));

splitPane.setDividerLocation(160);

splitPane.setPreferredSize(new Dimension(500, 300));

Container contentPane = getContentPane();

contentPane.add(splitPane);

setSize(400, 150);

setVisible(true);

}

public void update(){

try{

URL url = model.getCarFileURL();

editorPane.setPage(url);

System.out.println("We have beencalled.");

}

catch (IOException e){

e.printStackTrace();

}

ImageIcon imIcon = model.getImageIcon();

imgLabel.setIcon(imIcon);

imgLabel.validate();

}

}

import java.awt.*;

importjavax.swing.*;

public classCarBitView extends JFrame implements View{

private JPanel showPanel;

private JLabel bitOfferedLabel;

private JTextArea bitText;

private CarModel model;

//public CarBitView(CarModel cmodel) throwsException{

public CarBitView(CarModel cmodel) {

super("Car Bit Info View- Observer2");

model = cmodel;

bitOfferedLabel = newJLabel("Latest bit offered:");

bitText = new JTextArea(4, 20);

bitText.setFont(newFont("Serif", Font.PLAIN, 14));

bitText.setLineWrap(true);

bitText.setWrapStyleWord(true);

Container contentPane =getContentPane();

contentPane.add(bitOfferedLabel,BorderLayout.NORTH);

contentPane.add(bitText,BorderLayout.CENTER);

setSize(400, 150);

setVisible(true);

}

public void update(){

System.out.println("Car bit hasbeen called.");

String sCar= model.getSelectedCar();

String pr = model.getBitPrice();

bitText.append("\n Bit price for"+ sCar + "="+ pr);

}

}// end ofclass

控制器Controller负责根据CarAuctionGUI对象输入的客户选择信息更新CarModel的数据。

importjava.awt.event.*;

importjavax.swing.*;

importjava.net.URL;

classController implements ActionListener{

private CarAuctionGUI objCarGui;

private CarModel cm;

private CarGUIView civ;

private CarBitView cb;

private String carPrice;

private String[] carList;

public Controller(CarAuctionGUIobjCarGui,CarModel cm,

CarGUIView civ,CarBitViewcb){

this.objCarGui = objCarGui;

this.cm=cm;

this.civ=civ;

this.cb=cb;

carList = objCarGui.getCarList();

cm.setCarList(carList);

}

public void actionPerformed(ActionEvent e){

String searchResult = null;

if(e.getActionCommand().equals(CarAuctionGUI.EXIT)){

System.exit(1);

}

if(e.getActionCommand().equals(CarAuctionGUI.SEARCH)){

String selectedCar =objCarGui.getSelectedCar();

cm.setSelectedCar(selectedCar);

cm.setCarFileURL();

cm.setupImageIcon();

cm.tell(civ);

}

if(e.getActionCommand().equals(CarAuctionGUI.BIT)){

carPrice = objCarGui.getBitPrice();

cm.setBitPrice(carPrice);

cm.tell(cb);

}

}

} // End ofclass Controller

importjava.awt.*;

import java.util.*;

import javax.swing.*;

import java.io.*;

import java.net.URL;

import java.awt.event.*;

import com.sun.java.swing.plaf.windows.*;

public classCarAuctionGUI extends JPanel {

private JTextField bitInputText;

private JLabel lblCarModel;

private JPanel buttonPanel;

private String[] carList;

private JComboBox cmbCarList;

private static CarModel cm;

private static CarGUIView civ;

private static CarBitView cb;

public static final String SEARCH ="Search";

public static final String BIT ="Bit";

public static final String EXIT ="Exit";

public CarAuctionGUI(){

super(new GridLayout(1,0));

setUpGUI();

}

private void setUpGUI(){

cmbCarList = new JComboBox();

String[] cl = getCarList();

setUpCarList(cl);

lblCarModel = new JLabel("Cars on auction:");

//Create the open button

JButton srchButton = new JButton(SEARCH);

srchButton.setMnemonic(KeyEvent.VK_S);

JButton exitButton = new JButton(EXIT);

exitButton.setMnemonic(KeyEvent.VK_X);

JButton bitButton = new JButton(BIT);

bitButton.setMnemonic(KeyEvent.VK_X);

bitInputText = new JTextField("Offeryour bit price",12);

buttonPanel = new JPanel();

//****************************************************

GridBagLayout gridbag = newGridBagLayout();

buttonPanel.setLayout(gridbag);

GridBagConstraints gbc = new GridBagConstraints();

buttonPanel.add(lblCarModel);

buttonPanel.add(cmbCarList);

buttonPanel.add(srchButton);

buttonPanel.add(bitButton);

buttonPanel.add(exitButton);

buttonPanel.add(bitInputText);

gbc.insets.top = 5;

gbc.insets.bottom = 5;

gbc.insets.left = 5;

gbc.insets.right = 5;

gbc.anchor = GridBagConstraints.EAST;

gbc.gridx = 0;

gbc.gridy = 0;

gridbag.setConstraints(lblCarModel, gbc);

gbc.anchor = GridBagConstraints.WEST;

gbc.gridx = 1;

gbc.gridy = 0;

gridbag.setConstraints(cmbCarList, gbc);

gbc.anchor = GridBagConstraints.EAST;

gbc.insets.left = 2;

gbc.insets.right = 2;

gbc.insets.top = 25;

gbc.anchor = GridBagConstraints.EAST;

gbc.gridx = 0;

gbc.gridy = 3;

gridbag.setConstraints(srchButton, gbc);

gbc.anchor = GridBagConstraints.WEST;

gbc.gridx = 1;

gbc.gridy = 3;

gridbag.setConstraints(exitButton, gbc);

gbc.gridx = 0;

gbc.gridy = 4;

gridbag.setConstraints(bitButton, gbc);

gbc.gridx = 1;

gbc.gridy = 4;

gridbag.setConstraints(bitInputText,gbc);

Controller objButtonHandler = newController(this,cm,civ,cb);

srchButton.addActionListener(objButtonHandler);

exitButton.addActionListener(objButtonHandler);

bitButton.addActionListener(objButtonHandler);

add(buttonPanel);

setSize(new Dimension(800, 450));

setVisible(true);

}

public String getSelectedCar() {

return (String) cmbCarList.getSelectedItem();

}

public String getBitPrice(){

return       bitInputText.getText();

}

// get the names of all the .html filesin a directory

public String[] getCarList(){

File f = new File("CarFiles");

String [] fileNames = f.list();

for(int i=0; i<fileNames.length; i++ ){

int len = fileNames[i].length();

fileNames[i]=fileNames[i].substring(0,len-5);

}

return fileNames;

}

public void setUpCarList(String[]carList){

for(int k=0; k<carList.length; k++) {

cmbCarList.addItem(carList[k]);

}

}

private static void createAndShowGUI() {

JFrame.setDefaultLookAndFeelDecorated(true);

JFrame frame = new JFrame("MVCpattern demo");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

CarAuctionGUI newContentPane = newCarAuctionGUI();

newContentPane.setOpaque(true);

frame.setContentPane(newContentPane);

//Display the window.

frame.pack();

frame.setVisible(true);

}

static public void main(String argv[]) {

javax.swing.SwingUtilities.invokeLater(newRunnable() {

public void run() {

cm = new CarModel();

civ= new CarGUIView(cm);

cb = new CarBitView(cm);

createAndShowGUI();

}

});

}

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-09 16:15:13

MVC风格的相关文章

React-Redux与MVC风格

刚接触React的时候,有人感叹这不就是当年的JSP吗?直接用代码生成html,两者混在一起,还真有不少人喜欢把事件响应和业务逻辑都写在component里面,看起来就头疼.当年的JSP已经被MVC所终结,我们可以借鉴MVC的思想让React-Redux的代码好写又好看. 先回顾一下MVC思想,如下图: 用户的请求先由Controller进行处理,处理后的数据放入Model,View根据Model的数据渲染界面呈现在用户面前. React-Redux中应用MVC: 1. Model 对应Redu

Python著名的lib和开发框架(均为转载)

第一,https://github.com/vinta/awesome-python Awesome Python A curated list of awesome Python frameworks, libraries, software and resources. Inspired by awesome-php. Awesome Python Admin Panels Algorithms and Design Patterns Anti-spam Asset Management A

点燃圣火! Ember.js 的初学者指南

转自:http://www.adobe.com/cn/devnet/html5/articles/flame-on-a-beginners-guide-to-emberjs.html 作者 Andy Matthews 现在,到处都可以看到复杂的 JavaScript 应用程序. 由于这些应用程序变得越来越复杂,一长串的 jQuery 回调语句,或者通过应用程序在各个点执行不同的函数调用,这些都变得无法再让人接受. 这导致了 JavaScript 开发人员了解到传统的软件程序员已经知道了几十年的问

【Web API系列教程】2.1 — ASP.NET Web API中的路由机制

这篇文章描述了ASP.NET Web API如何将HTTP请求发送(路由)到控制器. 备注:如果你对ASP.NET MVC很熟悉,你会发现Web API路由和MVC路由非常相似.主要区别是Web API使用HTTP方法来选择动作(action),而不是URI路径.你也可以在Web API中使用MVC风格的路由.这篇文章不需要ASP.NET MVC的任何知识. 路由表 在ASP.NET Web API中,控制器是一个用于处理HTTP请求的类.控制器中的公共方法被称为动作方法或简单动作.当Web A

软件体系结构基本概念汇总

这门课与UML建模,程序设计方法学一样,都是站在比较高的角度来看整个软件结构.并不是对算法,或者语言的关注.如果以后有志于成为软件架构师,就应该好好学这门课.现在我把自己整理的这门课的资料与大家分享. 二.名词解释(每题2分,共20分) 1.B/S(期中) 答:浏览器/服务器风格,是三层应用结构的一种实现方式. 具体结构:浏览器/Web服务器/数据库服务器. 2.C/S(期中) 答:客户/服务器风格,是基于资源不对等,且为共享而提出来的,定义了工作站如何与服务器相连,以实现数据和应用分布到多个处

etxjs

序言 编辑 功能丰富,无人能出其右. 无论是界面之美,还是功能之强,ext的表格控件都高居榜首. 单选行,多选行,高亮显示选中的行,拖拽改变列宽度,按列排序,这些基本功能ExtJS轻量级实现. 自动生成行号,支持checkbox全选,动态选择显示哪些列,支持本地以及远程分页,可以对单元格按照自己的想法进行渲染,这些也算可以想到的功能. 再加上可编辑grid,添加新行,删除一或多行,提示多行数据,拖拽改变grid大小,grid之间拖拽一或多行,甚至可以在tree和grid之间进行拖拽,这些功能实在

《Getting MEAN with Mongo Express Angular and Node》---ch08 Adding Angular components to an Express application(向Express应用添加Angular组件)

This chapter covers(本章概要)■ Getting to know Angular(了解Angrular)■ Adding Angular to an existing page(向动态页面添加Angular)■ Filtering lists of data(过滤列表数据)■ Using an API for reading data(使用API读取数据)■ Some Angular jargon: controllers, scope, filters,directives

Web API路由与动作(三)

本章包括三个小节  如果你输入了mvc的路由规则 这个可以粗略过一遍即可  内容说明有点繁琐 原文地址:http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api 3.1ASP.NET Web API中的路由 本节描述ASP.NET Web API如何将HTTP请求路由到控制器 如果你熟悉ASP.NET MVC,Web API路由与MVC路由十分类似.主要差别是Web API使

SnakeGo : Scaling Screen on Stage II

昨晚把BaseScreen就敲好了, 也找到了屏幕放缩的最优和最简方式. 不多说, 看代码: public BaseScreen(final SnakeGo game) { super(new ScalingViewport(Scaling.fit, CommonConsts.Screen.WIDTH, CommonConsts.Screen.HEIGHT, new OrthographicCamera()), new SpriteBatch()); this.game = game; Gdx.