Model-View-Controller

MVC模式是个威力强大的复合模式,是由数个设计模式结合起来的模式;

我们先看一下一个mp3播放器的设计,来由浅至深地了解这个设计模式的精髓所在:

从最直观的地方入手,我们不要先入为主的去使用mvc这个模式,而是尝试用自己最为直观的方式去设计这个应用,那么事情会变成这样:

首先从交互的角度,我们先提出需求:

  • 用户界面上需要显示当前歌曲名
  • 用户可以通过按键直接选择上一首,下一首;
  • 用户可以通过menu按键,显示当前MP3中的所有歌曲列表,然后上下按键选择一首歌曲,并通过ok键播放

好的,其实上述需求,明确了一点,这些需求需要有视图,或者至少需要有View去告诉用户各种状态;ok,那有没有不需要view的需求呢?有,比如,按下风扇能转动,这种需求很简单就不需要view, 但是,这不是重点,重点在于,用户需要对机器当前的状态有个直观的感知,或者反馈,比如风扇上如果我们想要做高端,然后会加个面板,告诉用户当前的风速,室内温度等,最终还是免不了会有view的存在,view的形式可以是多样的,可以是网页的形式,可以是led的形式,可以是数码管的形式,这些只是展示方式的不同,真正的核心在于这些view展示的数据本身,这些才是用户真正care的地方;比如我的歌单里有没有某首歌(模型),比如我播放下一曲的时候,是否能正常切过去(控制器);简单总结就是:用户操作,会作用于控制器,控制器判断用户需要切歌,需要更改当前播放的歌曲索引,然后通知player 播放新的歌曲;模型的改变,会相应地引起视图的改变 ;

那么这里使用了哪些设计模式呢?

这里复习一下观察者模式和策略模式:

观察者模式的好处在于,模型对视图没有依赖,其含义是模型部分无需变更,便可以支持视图的替换,或多个视图去展示同一个模型;

纸上得来终觉浅,我们还是从代码的角度来看一下整个事情的细节吧:

class Mp3Model {
public:
int getSongIdxByString(string song);
string getSoneNameByIdx(int idx);
string getCurrentSong() void setCurrentSong(string song) {
// hw hal to set song file
...
// then notify observers
notifyObserver(); // 通知观察者状态改变
}
// 实际的start/stop
void start();
void stop();
void registerObsever(Observer* observer) // model提供注册观察者方法
{
mObserver = observer;
}
private:
void notifyObserver() {
mObserver->onNotify();
}
Observer* mObserver;
}; class Mp3Controller {
public:
Mp3Controller(Mp3Model* model) { mModel = model; }
void playNext() {
mModel->setCurrentSong(mModel->getSongIdxByString(mModel->getCurrentSong()) + 1);
}
void playPrevious() {
mModel->setCurrentSong(mModel->getSongIdxByString(mModel->getCurrentSong()) - 1);
}
void start() { mModel->start();}
void stop() { mModel->stop(); }
private:
Mp3Model* mModel;
}; class Mp3View : public Observer {
public:
Mp3View() {
mModel = new Mp3Model;
mModel->registerObserver((Oberver*)this);
mController = new Mp3Controller(mModel);
}
void on_click_next() { mController->playNext(); }
void on_click_previous() { mController->playPrevious(); }
void on_click_start() { mContrlloer->start(); }
void on_click_stop() { mController->stop(); }
void onNotify() { //实现model变化时的回调,如改变控件状态等 }
void run();
bool live();
private:
Mp3Controller* mController;
Mp3Model* mModel;
}; int main() {
// 创建view需要controller, mode , 创建controller需要model
Mp3View* mp3_view = new Mp3View;
mp3_view.run();
while(mp3_view.live()) {
sleep(1);
}
return 0;
}

对mvc模式的理解的更多相关文章

  1. ios开发中MVC模式的理解

    MVC是80年代出现的一种软件设计模式,是模型(model),视图(view)和控制(Controller)的缩写. 其中Model的主要功能包括业务逻辑的处理以及数据的访问,这是应用程序的主体部分. ...

  2. mvc模式的理解

    一开始总是觉得dao层和service层没有区别,甚至觉得service层根本就是多余的,service层就是把dao层的内容调用了一下,然后重写了一次,后来才理解到,dao层是数据链路层,是与数据库 ...

  3. JSP的执行原理、JSP的内置对象、四大作用域解析、MVC模式理解>从零开始学JAVA系列

    目录 JSP的执行原理.JSP的内置对象.四大作用域解析.MVC模式理解 JSP的执行原理 这里拿一个小例子来解析JSP是如何被访问到的 首先将该项目部署到tomcat,并且通过tomcat启动 通过 ...

  4. 二十八、带给我们一种新的编码思路——EFW框架CS系统开发中的MVC模式探讨

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...

  5. Android MVC模式

    Android MVC模式 下面是我对Android MVC模式的理解 Model 模型层 包括实体模型层,存放程序中调用的实体. 业务模型层,存放程序中调用的业务逻辑.   View 显示层  An ...

  6. 传统的MVC模式

    对于MVC模式,我们可以将可视化UI呈现,UI处理逻辑和业务逻辑分别定义在View,Controller,和Model中. 可视化UI呈现->View UI处理逻辑->Controller ...

  7. 使用jdbc实现简单的mvc模式的增删改查

    Mvc模式设计: 视图:添加界面(addUser.jsp),修改界面(updateUser.jsp),显示页面(allUser.jsp) 控制器:添加信息控制器(AddUserServlet),修改信 ...

  8. [ASP.NET MVC 小牛之路]01 - 理解MVC模式

    本人博客已转移至:http://www.exblr.com/liam  PS:MVC出来很久了,工作上一直没机会用.出于兴趣,工作之余我将展开对MVC的深入学习,通过博文来记录所学所得,并希望能得到各 ...

  9. 生活中的MVC模式,一个吃货的理解。

    以下是生活中对于MVC模式的领悟,虽然可笑,轻喷. 2015年 8月 26日 M  => Model       模型 我认为叫做模具更好的理解.批量加工生产具有相同特征的东西.        ...

  10. 理解MVC模式

    理解一般意义上的MVC模式 MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为以下三个基本部分: 模型(Model):模型用于封装与应用程序的业务逻 ...

随机推荐

  1. ASP.NET Core - 依赖注入(四)

    4. ASP.NET Core默认服务 之前讲了中间件,实际上一个中间件要正常进行工作,通常需要许多的服务配合进行,而中间件中的服务自然也是通过 Ioc 容器进行注册和注入的.前面也讲到,按照约定中间 ...

  2. 代数余子式的由来/代数余子式为什么-1的系数是ⁱ⁺ʲ?/证明一个n阶行列式,如果其中第i行(或第j列)所有元素除aᵢⱼ外都为零,那么这行列式等于aᵢⱼ与它的代数余子式的乘积/证明行列式按行(列)展开法则:n(n>1)阶行列式等于它任意一行(列)的所有元素与它们对应的代数余子式的乘积的和。

    代数余子式的由来/代数余子式为什么-1的系数是ⁱ⁺ʲ?/证明一个n阶行列式,如果其中第i行(或第j列)所有元素除aᵢⱼ外都为零,那么这行列式等于aᵢⱼ与它的代数余子式的乘积/证明行列式按行(列)展开法 ...

  3. Vulnhub:ReconForce-01.1靶机

    kali:192.168.111.111 靶机:192.168.111.200 信息收集 端口扫描 nmap -A -v -sV -T5 -p- --script=http-enum 192.168. ...

  4. sql server 主键自增

    ALTER TABLE tableName ADD column INT IDENTITY (1, 1);

  5. 关于服务器上的XML

    服务器上的 XML XML 文件是类似 HTML 文件的纯文本文件. XML 能够通过标准的 Web 服务器轻松地存储和生成. 在服务器上存储 XML 文件 XML 文件在 Internet 服务器上 ...

  6. go 程序设计语言 命令行参数

    最近打算读一读 go程序设计语言这本书, 读语言类的书是一件十分头疼的事情, 因为读一本书就意味着,看着一堆钳子 锥子工具的图片, 概念背了一大堆,仍然不知道怎么用,还是要通过实践. 还是习惯任务驱动 ...

  7. vscode的python开发环境搭建,环境变量支持终端命令行(执行当前

    vscode的python开发环境设置 安装vscode,这里不介绍了 安装插件 在${workspaceFolder}的目录下,新建.vscode文件夹(或者修改一下配置,也可以自动生成该文件夹) ...

  8. Java--Comparable接口实现,控制数组和列表的排序

    实现Comparable 接口,可以获得的排序方法有 列表排序 Collections.sort(); 数组排序 Arrays.sort(); sort()方法中的参数是可以获取排序索引的对象或者按照 ...

  9. 工作日统计工具(python)

    一.前言 最近在整理之前写过的工具,发现这个虽然写得很简单,但是现在回头看看还挺有趣,就放出来LOL 记得应该是因为当初写立项书的时候,总是得算10个工作日之后是几号,或者到几号结束还剩下多少个工作日 ...

  10. reids 启动方法

    ---恢复内容开始--- 在windows环境下启动redis服务,前提是你安装好了,启动如下: 一,进入redis的安装目录下,在地址栏输入"cmd",回车 二,然后会进入cmd ...