1. 应用场景

MVC设计模式广泛应用于桌面应用程序开发和网页页面开发这些与用户交互的应用场景中。

2.概念

众所周知MVC不是设计模式,是一个比设计模式更大一点的模式,称作设计模式不合理,应该说MVC它是一种软件开发架构模式,它包含了很多的设计模式,最为密切是以下三种:Observer (观察者模式), Composite(组合模式)和Strategy(策略模式)。所以说MVC模式又称复合模式。MVC(Model-View-Controller) 模式的基本思想是数据,显示和处理相分离。模型(Model)负责数据管理,视图(View)负责数据显示,控制器(Controller)负责业务逻辑和响应策略。

MVC是一种设计模式,强制地把应用程序的输入,处理和输出分开,把应用程序分成三个核心模块:Model,View和Console。

  • View:

    • 视图是用户看到并与之交互的界面,视图向用户显示相关的数据,并能接收用户的输入数据,但是它不进行任何的业务处理;
    • 视图可以向模型查询业务状态,但不能改变模型;
    • 视图还能接收模型发出的数据更新事件,从而对用户界面进行同步更新。
  • Model:

    • 模型是应用程序的主体部分,表示业务数据和业务逻辑。一个模型能为多个View提供数据,由于同一个模型可以被多个视图重用,所以提高了应用的可重用性。
  • Controller:

    • 控制器接收用户的输入并调用模型和视图去完成用户请求,当Web用户单击页面中的提交按钮来发送html表单时,控制器接收请求并调用相应模型组件去处理请求,然后调用相应的视图来显示模型返回的数据。

3. Class Digram

3.1 Model (模型端)

Mod封装的是数据源和所有基于对这些数据的操作。在一个组件中,Model往往表示组件的状态和操作这些状态的方法,往往是一系列的公开方法。通过这些公开方法,便可以取得模型端的所有功能。

在这些公开方法中,有些是取值方法,让系统其他部分可以得到模型端的内部状态参数,其他的改值方法则允许外部修改模型端的内部状态。模型端还必须有方法登记视图,以便在模型端的内部状态发生变化时,可以通知视图端。我们可以自己定义一个Subject接口来提供登记和通知视图所需的接口或者继承 Java.util.Observable类,让父类完成这件事。

3.2 多个 View( 视图端 )

View封装的是对数据源Model的一种显示。一个模型可以由多个视图,并且可以在需要的时候动态地登记上所需的视图。而一个视图理论上也可以同不同的模型关联起来。

在前言里提到了,MVC模式用到了合成模式,这是因为在视图端里,视图可以嵌套,比如说在一个JFrame组件里面,可以有菜单组件,很多按钮组件等。

3.3 多个 Controller( 控制器端 )

封装的是外界作用于模型的操作。通常,这些操作会转发到模型上,并调用模型中相应的一个或者多个方法(这个方法就是前面在介绍模型的时候说的改值方法)。一般Controller在Model和View之间起到了沟通的作用,处理用户在View上的输入,并转发给Model来更改其状态值。这样 Model和View两者之间可以做到松散耦合,甚至可以彼此不知道对方,而由Controller连接起这两个部分。也在前言里提到,MVC用到了策略模式,这是因为View用一个特定的Controller的实例来实现一个特定的响应策略,更换不同的Controller,可以改变View对用户输入的响应。

3.4 MVC (Model-View-Controller)

MVC (Model-View-Controller) : 模型利用"观察者"让控制器和视图可以随最新的状态改变而更新。另一方面,视图和控制器则实现了"策略模式"。控制器是视图的行为; 视图内部使用"组合模"式来管理显示组件。

以下的MVC解释图很好的标示了这种模式:

  • 模型使用观察者模式,以便观察者更新,同时保持两者之间的解耦。
  • 控制器是视图的策略,视图可以使用不同的控制器实现,得到不同的行为。
  • 视图使用组合模式实现用户界面,用户界面通常组合了嵌套的组件,像面板、框架和按钮。

这些模式携手合作,把MVC模式的三层解耦,这样可以保持设计干净又有弹性。

4. Implementation

一个DJView 的Java Swing程序

MVC Model 类public interface BeatModelInterface {void initialize();void on();void off();void setBPM(int bpm);int getBPM();void registerObserver(BeatObserver o);void removeObserver(BeatObserver o);void registerObserver(BPMObserver o);void removeObserver(BPMObserver o);void notifyBPMObservers();void notifyBeatObservers();
}public interface BeatObserver {void updateBeat();
}public interface BPMObserver {void updateBPM();
}public class BeatModel implements BeatModelInterface, MetaEventListener {Sequencer sequencer;ArrayList<BeatObserver> beatObservers = new ArrayList<BeatObserver>();ArrayList<BPMObserver> bpmObservers = new ArrayList<BPMObserver>();int bpm = 90;Sequence sequence;Track track;public void initialize() {setUpMidi();buildTrackAndStart();}public void on() {System.out.println("Starting the sequencer");sequencer.start();setBPM(90);}public void off() {setBPM(0);sequencer.stop();}public void setBPM(int bpm) {this.bpm = bpm;sequencer.setTempoInBPM(getBPM());notifyBPMObservers();}public int getBPM() {return bpm;}void beatEvent() {notifyBeatObservers();}public void registerObserver(BeatObserver o) {beatObservers.add(o);}public void notifyBeatObservers() {for(int i = 0; i < beatObservers.size(); i++) {BeatObserver observer = (BeatObserver)beatObservers.get(i);observer.updateBeat();}}public void registerObserver(BPMObserver o) {bpmObservers.add(o);}public void notifyBPMObservers() {for(int i = 0; i < bpmObservers.size(); i++) {BPMObserver observer = (BPMObserver)bpmObservers.get(i);observer.updateBPM();}}public void removeObserver(BeatObserver o) {int i = beatObservers.indexOf(o);if (i >= 0) {beatObservers.remove(i);}}public void removeObserver(BPMObserver o) {int i = bpmObservers.indexOf(o);if (i >= 0) {bpmObservers.remove(i);}}public void meta(MetaMessage message) {if (message.getType() == 47) {beatEvent();sequencer.start();setBPM(getBPM());}}public void setUpMidi() {try {sequencer = MidiSystem.getSequencer();sequencer.open();sequencer.addMetaEventListener(this);sequence = new Sequence(Sequence.PPQ,4);track = sequence.createTrack();sequencer.setTempoInBPM(getBPM());sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);} catch(Exception e) {e.printStackTrace();}} public void buildTrackAndStart() {int[] trackList = {35, 0, 46, 0};sequence.deleteTrack(null);track = sequence.createTrack();makeTracks(trackList);track.add(makeEvent(192,9,1,0,4));      try {sequencer.setSequence(sequence);                    } catch(Exception e) {e.printStackTrace();}} public void makeTracks(int[] list) {        for (int i = 0; i < list.length; i++) {int key = list[i];if (key != 0) {track.add(makeEvent(144,9,key, 100, i));track.add(makeEvent(128,9,key, 100, i+1));}}}public  MidiEvent makeEvent(int comd, int chan, int one, int two, int tick) {MidiEvent event = null;try {ShortMessage a = new ShortMessage();a.setMessage(comd, chan, one, two);event = new MidiEvent(a, tick);} catch(Exception e) {e.printStackTrace(); }return event;}
}MVC Controller 类
public interface ControllerInterface {void start();void stop();void increaseBPM();void decreaseBPM();void setBPM(int bpm);
}public class BeatController implements ControllerInterface {BeatModelInterface model;DJView view;public BeatController(BeatModelInterface model) {this.model = model;view = new DJView(this, model);view.createView();view.createControls();view.disableStopMenuItem();view.enableStartMenuItem();model.initialize();}public void start() {model.on();view.disableStartMenuItem();view.enableStopMenuItem();}public void stop() {model.off();view.disableStopMenuItem();view.enableStartMenuItem();}public void increaseBPM() {int bpm = model.getBPM();model.setBPM(bpm + 1);}public void decreaseBPM() {int bpm = model.getBPM();model.setBPM(bpm - 1);}public void setBPM(int bpm) {model.setBPM(bpm);}
}MVC View 类
public class BeatBar extends JProgressBar implements Runnable { private static final long serialVersionUID = 2L;JProgressBar progressBar;Thread thread;public BeatBar() {thread = new Thread(this);setMaximum(100);thread.start();}public void run() {for(;;) {int value = getValue();value = (int)(value * .75);setValue(value);repaint();try {Thread.sleep(50);} catch (Exception e) {};}}
}public class DJView implements ActionListener, BeatObserver, BPMObserver {BeatModelInterface model;ControllerInterface controller;JFrame viewFrame;JPanel viewPanel;BeatBar beatBar;JLabel bpmOutputLabel;JFrame controlFrame;JPanel controlPanel;JLabel bpmLabel;JTextField bpmTextField;JButton setBPMButton;JButton increaseBPMButton;JButton decreaseBPMButton;JMenuBar menuBar;JMenu menu;JMenuItem startMenuItem;JMenuItem stopMenuItem;public DJView(ControllerInterface controller, BeatModelInterface model) {    this.controller = controller;this.model = model;model.registerObserver((BeatObserver)this);model.registerObserver((BPMObserver)this);}public void createView() {// Create all Swing components hereviewPanel = new JPanel(new GridLayout(1, 2));viewFrame = new JFrame("View");viewFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);viewFrame.setSize(new Dimension(100, 80));bpmOutputLabel = new JLabel("offline", SwingConstants.CENTER);beatBar = new BeatBar();beatBar.setValue(0);JPanel bpmPanel = new JPanel(new GridLayout(2, 1));bpmPanel.add(beatBar);bpmPanel.add(bpmOutputLabel);viewPanel.add(bpmPanel);viewFrame.getContentPane().add(viewPanel, BorderLayout.CENTER);viewFrame.pack();viewFrame.setVisible(true);}public void createControls() {// Create all Swing components hereJFrame.setDefaultLookAndFeelDecorated(true);controlFrame = new JFrame("Control");controlFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);controlFrame.setSize(new Dimension(100, 80));controlPanel = new JPanel(new GridLayout(1, 2));menuBar = new JMenuBar();menu = new JMenu("DJ Control");startMenuItem = new JMenuItem("Start");menu.add(startMenuItem);startMenuItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {controller.start();}});stopMenuItem = new JMenuItem("Stop");menu.add(stopMenuItem); stopMenuItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {controller.stop();}});JMenuItem exit = new JMenuItem("Quit");exit.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {System.exit(0);}});menu.add(exit);menuBar.add(menu);controlFrame.setJMenuBar(menuBar);bpmTextField = new JTextField(2);bpmLabel = new JLabel("Enter BPM:", SwingConstants.RIGHT);setBPMButton = new JButton("Set");setBPMButton.setSize(new Dimension(10,40));increaseBPMButton = new JButton(">>");decreaseBPMButton = new JButton("<<");setBPMButton.addActionListener(this);increaseBPMButton.addActionListener(this);decreaseBPMButton.addActionListener(this);JPanel buttonPanel = new JPanel(new GridLayout(1, 2));buttonPanel.add(decreaseBPMButton);buttonPanel.add(increaseBPMButton);JPanel enterPanel = new JPanel(new GridLayout(1, 2));enterPanel.add(bpmLabel);enterPanel.add(bpmTextField);JPanel insideControlPanel = new JPanel(new GridLayout(3, 1));insideControlPanel.add(enterPanel);insideControlPanel.add(setBPMButton);insideControlPanel.add(buttonPanel);controlPanel.add(insideControlPanel);bpmLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));bpmOutputLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));controlFrame.getRootPane().setDefaultButton(setBPMButton);controlFrame.getContentPane().add(controlPanel, BorderLayout.CENTER);controlFrame.pack();controlFrame.setVisible(true);}public void enableStopMenuItem() {stopMenuItem.setEnabled(true);}public void disableStopMenuItem() {stopMenuItem.setEnabled(false);}public void enableStartMenuItem() {startMenuItem.setEnabled(true);}public void disableStartMenuItem() {startMenuItem.setEnabled(false);}public void actionPerformed(ActionEvent event) {if (event.getSource() == setBPMButton) {int bpm = Integer.parseInt(bpmTextField.getText());controller.setBPM(bpm);} else if (event.getSource() == increaseBPMButton) {controller.increaseBPM();} else if (event.getSource() == decreaseBPMButton) {controller.decreaseBPM();}}public void updateBPM() {if (model != null) {int bpm = model.getBPM();if (bpm == 0) {if (bpmOutputLabel != null) {bpmOutputLabel.setText("offline");}} else {if (bpmOutputLabel != null) {bpmOutputLabel.setText("Current BPM: " + model.getBPM());}}}}public void updateBeat() {if (beatBar != null) {beatBar.setValue(100);}}
}

5. JDK

  • Java Web
  • JavaSwing

Java设计模式(十四):MVC设计模式相关推荐

  1. 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)

    设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的有用 ...

  2. Java第十四课——相声和群口相声

    Java第十四课--相声和群口相声 Java第十四课--相声和群口相声 一.聊天界面优化 二.增加发送内容的样式 三.群聊雏形 相声,我们知道有一个逗哏一个捧哏,也就是一唱一和,也就相当于双向的交流. ...

  3. Java——Web开发之MVC设计模式的学生信息管理系统(二)

    为什么这个标题为"(二)",其实是对于上一个特别简单学生信息管理系统里功能的完善. 所谓的"(一)"在这:学生信息管理系统(一) 系统实现的功能: 实现添加学生 ...

  4. MVC设计模式及Sprint MVC设计模式

    文章目录 一.MVC设计模式简介 二.Spring MVC处理用户请求的完整流程 2.1. Spring MVC 框架主要由 DispatcherServlet.处理器映射.控制器.视图解析器.视图组 ...

  5. php的mvc设计模式,什么是MVC设计模式?,

    详细内容 Model View Controller简称MVC,即模型视图控制器.MVC设计模式指定应用程序由数据模型.呈现信息和控制信息组成.该模式要求将每个模式分成不同的对象. MVC更像是一种架 ...

  6. java第十四章上机四客户类_java语言程序设计教学大纲.doc

    java语言程序设计教学大纲.doc 还剩 5页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: 第六章 结构控制 2 2第七章 数组 2第八章 字符串 ...

  7. [原创]java WEB学习笔记18:java EE 中的MVC 设计模式(理论)

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  8. Java设计模式(十):迭代器设计模式

    1.应用场景 (1)访问一个聚合对象的内容而无需暴露它的内部表示 (2)支持对聚合对象的多种遍历 (3)为遍历不同的聚合结构提供一个统一的接口 2.概念 提供一种顺序访问聚合对象元素的方法,并且不暴露 ...

  9. 二十四种设计模式之策略模式

    一.什么是策略模式? 简单来说,策略模式是将每一个算法封装到拥有共同接口的不同类中,使得算法可以在不影响客户端的情况下发生变化.(也可以理解为可供程序运行时选择的(不同的类==不同的解决方案)). 策 ...

最新文章

  1. ACMNO.39 分解质因数 求出区间[a,b]中所有整数的质因数分解。蓝桥杯训练!
  2. 静态程序分析chapter3 - 数据流分析详述(Reaching Definitions、Live Variables、Available Expressions Analysis)
  3. 七、Java编码字符集和转义符介绍
  4. 全国计算机等级考试题库二级C操作题100套(第09套)
  5. c语言中组合函数,排列组合c怎么算 公式是什么
  6. SAP License:什么是ERP、SAP?
  7. 门槛低的行业看天赋,门槛高的行业看毅力
  8. Bailian2808 校门外的树【基础】
  9. IOS动画隐式,显式,翻页
  10. revit插件有哪些常用的?介绍几个常用的revit插件操作简单
  11. 《软件工程》实训报告
  12. java候选码计算的替换法_候选码求解方法
  13. 第一章、linux入门及基本命令(案例讲解)
  14. 微信小程序:简单舒服新UI装逼制作神器
  15. 微信公众号开发:用从微信服务器下载图片资源
  16. 计算机网络原理(谢希仁第八版)第三章课后习题答案
  17. 大学生三个痛点及分析
  18. 安装apache遇到You don’t have permission to access this resource. 原因与解决方法
  19. tiktok设备注册+xg xk xl xa签名
  20. 仿百度首页登陆框拖拽效果(可视窗口内拖动)

热门文章

  1. 牛客(35)数组中的逆序对
  2. oracle的游标cursor
  3. python函数 一
  4. OAuth2.0学习(1-6)授权方式3-密码模式(Resource Owner Password Credentials Grant)
  5. 解决安装python第三方模块 '-mno-cygwin'报错的问题
  6. 40.简述操作系统中调用过程?
  7. 一篇文章解决机器学习,深度学习入门疑惑
  8. 只需十四步:从零开始掌握 Python 机器学习(附资源)
  9. 近期发现的一些-20190519
  10. 中山大学2020计算机学院复试分数线,2020中山大学研究生分数线汇总(含2016-2020历年复试)...