linux设置自动转换壁纸

MVC,MVP和MVVM都是常见的软件架构设计模式(Architectural
Pattern),它通过分离关注点来改进代码的团组织方式。不同让设计模式(Design
Pattern),只是为解决一像样题目如总出之空洞方法,一栽架构模式往往使用了又设计模式。

#!/bin/bash
let n=0
files=($HOME/wallpapers/*.jpg)
count=${#files[@]}
while [ 1 ]
do
  let "n=n%$count"
  file="${files[$n]}"
  echo "switch to $file"
  feh --bg-max "$file" &
  let n=n+1
  sleep 5s
done

一经了解MVC、MVP和MVVM,就要了解它的相同点和不同点。不同部分是C(Controller)、P(Presenter)、VM(View-Model),而平之片段则是MV(Model-View)。

日前发觉上荣耀的壁纸很优秀,就描写了单机关转换壁纸的本子

Model&View

此地有一个可针对数值进行加减操作的组件:上面显示数价,两个按钮可以本着数值进行加减操作,操作后的数值会更新显示。

 图片 1

我们拿如约本条“栗子”,尝试用JavaScript实现简单的装有MVC/MVP/MVVM模式的Web应用。

 

Model

Model层用于封装和应用程序的业务逻辑相关的数与针对数码的拍卖措施。这里我们拿用运用的数值变量封装在Model中,并定义了add、sub、getVal三种操作数值方法。

var myapp = {}; // 创建这个应用对象

myapp.Model = function() {
    var val = 0; // 需要操作的数据

    /* 操作数据的方法 */
    this.add = function(v) {
        if (val < 100) val += v;
    };

    this.sub = function(v) {
        if (val > 0) val -= v;
    };

    this.getVal = function() {
        return val;
    };
};

View

View作为视图层,主要担负数据的展示。

myapp.View = function() {

    /* 视图元素 */
    var $num = $('#num'),
        $incBtn = $('#increase'),
        $decBtn = $('#decrease');

    /* 渲染数据 */
    this.render = function(model) {
        $num.text(model.getVal() + 'rmb');
    };
};

 

现今经Model&View完成了数码从模型层及视图层的逻辑。但对一个应用程序,这远是不够的,我们还索要应用户之操作、同步创新View和Model。于是,在MVC中引入了控制器controller,让她来定义用户界面对用户输入的响应措施,它总是模型与视图,用于控制应用程序的流程,处理用户的作为及数目及之改变。

 

MVC

当时计算机世界天地混沌,浑然一体,然后出现了一个创世者,将现实世界抽象出模型形成model,将人机交互从应用逻辑中分离形成view,然后便时有发生了气氛、水、鸡啊、蛋什么的。
——《前端MVC变形记》

上个世纪70年间,美国施乐帕克研究中心,就是杀发明图形用户界面(GUI)的号,开发了Smalltalk编程语言,并开用其编写图形界面的应用程序。

暨了Smalltalk-80这个本子的当儿,一各类受Trygve
Reenskaug的工程师也Smalltalk设计了MVC(Model-View-Controller)这种架构模式,极大地降落了GUI应用程序的保管难度,而后被大量用来构建桌面以及劳务器端应用程序。

 

图片 2

 

要是图,实线代表法调用,虚线代表事件通报。

MVC允许以无改变视图的动静下转视图对用户输入的响应措施,用户指向View的操作交给了Controller处理,在Controller中应View的轩然大波调用Model的接口对数据开展操作,一旦Model发生变化便通知相关视图进行翻新。

Model

Model层用来囤积业务的数据,一旦数据发生变化,模型将通知有关的视图。

myapp.Model = function() {
    var val = 0;

    this.add = function(v) {
        if (val < 100) val += v;
    };

    this.sub = function(v) {
        if (val > 0) val -= v;
    };

    this.getVal = function() {
        return val;
    };

    /* 观察者模式 */
    var self = this, 
        views = [];

    this.register = function(view) {
        views.push(view);
    };

    this.notify = function() {
        for(var i = 0; i < views.length; i++) {
            views[i].render(self);
        }
    };
};

Model和View之间使用了观察者模式,View事先在这个Model上注册,进而观察Model,以便更新在Model上闹变动之多少。

View

view和controller之间使用了方针模式,这里View引入了Controller的实例来实现特定的响应政策,比如是栗子中按钮的 click 事件:

myapp.View = function(controller) {
    var $num = $('#num'),
        $incBtn = $('#increase'),
        $decBtn = $('#decrease');

    this.render = function(model) {
        $num.text(model.getVal() + 'rmb');
    };

    /*  绑定事件  */
    $incBtn.click(controller.increase);
    $decBtn.click(controller.decrease);
};

假设要落实不同之应的政策要用不同的Controller实例替换即可。

Controller

控制器是范与视图之间的要点,MVC将响应机制封装于controller对象吃,当用户与你的行使来互动时,控制器中的事件触发器就开工作了。

myapp.Controller = function() {
    var model = null,
        view = null;

    this.init = function() {
        /* 初始化Model和View */
        model = new myapp.Model();
        view = new myapp.View(this);

        /* View向Model注册,当Model更新就会去通知View啦 */
        model.register(view);
        model.notify();
    };

    /* 让Model更新数值并通知View更新视图 */
    this.increase = function() {
        model.add(1);
        model.notify();
    };

    this.decrease = function() {
        model.sub(1);
        model.notify();
    };
};

此处我们实例化View并于对应之Model实例注册,当Model发生变化时即便夺通知View做创新,这里用了观察者模式。

当我们执行下之时节,使用Controller做初始化:

(function() {
    var controller = new myapp.Controller();
    controller.init();
})();

得判感觉到到,MVC模式之业务逻辑主要汇集在Controller,而前者的View其实已经持有了单独处理用户事件之力,当每个事件还流经Controller时,这层会变换得可怜层。而且MVC中View和Controller一般是各个对应之,捆绑起来表示一个组件,视图与操纵器间的超负荷紧密的连为Controller的复用性成了问题,如果想多只View共用一个Controller该怎么收拾为?这里发出一个解决方案:

 

图片 3

 

来把皇帝荣耀压压惊~其实我思说之是MVP模式…

MVP

MVP(Model-View-Presenter)是MVC模式之改进,由IBM的支行Taligent提出。和MVC的相同之处在于:Controller/Presenter负责业务逻辑,Model管理数据,View负责显示。

 

 

 图片 4

虽然在MVC里,View是可一直看Model的,但MVP中的View并无可知一直用Model,而是通过也Presenter提供接口,让Presenter去更新Model,再通过观察者模式创新View。

与MVC相比,MVP模式通过解耦View和Model,完全分离视图和模型如果职责分开更加分明;由于View不依赖Model,可以拿View抽离出来做成组件,它不过待提供平等密密麻麻接口提供被上层操作。

Model

myapp.Model = function() {
    var val = 0;

    this.add = function(v) {
        if (val < 100) val += v;
    };

    this.sub = function(v) {
        if (val > 0) val -= v;
    };

    this.getVal = function() {
        return val;
    };
};

Model层依然是根本跟业务相关的多寡以及指向许处理数量的主意。

View

myapp.View = function() {
    var $num = $('#num'),
        $incBtn = $('#increase'),
        $decBtn = $('#decrease');

    this.render = function(model) {
        $num.text(model.getVal() + 'rmb');
    };

    this.init = function() {
        var presenter = new myapp.Presenter(this);

        $incBtn.click(presenter.increase);
        $decBtn.click(presenter.decrease);
    };
};

MVP定义了Presenter和View之间的接口,用户对View的操作都易至了Presenter。比如这里的View暴露setter接口让Presenter调用,待Presenter通知Model更新后,Presenter调用View提供的接口更新视图。

Presenter

myapp.Presenter = function(view) {
    var _model = new myapp.Model();
    var _view = view;

    _view.render(_model);

    this.increase = function() {
        _model.add(1);
        _view.render(_model);
    };

    this.decrease = function() {
        _model.sub(1);
        _view.render(_model);
    };
};

Presenter作为View和Model之间的“中间人”,除了核心的作业逻辑外,还有大量代码需要针对自View到Model和由Model到View的多寡进行“手动同步”,这样Presenter显得煞是重复,维护起来会于困难。而且由于没数量绑定,如果Presenter对视图渲染之求大增,它只能过多关心特定的视图,一旦视图需求来转移,Presenter也欲改变。

运行程序时,以View为输入:

(function() {
    var view = new myapp.View();
    view.init();
})();

MVVM

MVVM(Model-View-ViewModel)最早由微软提出。ViewModel指 “Model of
View”——视图的模子。这个定义就当一段时间内让前端圈热炒,以至于许多初家拿jQuery和Vue做对比…

 

图片 5

 

MVVM把View和Model的共同逻辑自动化了。以前Presenter负责的View和Model同步不再手动地开展操作,而是交由框架所提供的数目绑定功能拓展承担,只需要报告她View显示的多少对应之是Model哪一部分即可。

这里我们采用Vue来完成这栗子。

Model

在MVVM中,我们得以管Model称为数据层,因为其只是关注数据我,不体贴其他表现(格式化数据由View的当),这里可以将她知道也一个看似json的多寡对象。

 

var data = {
    val: 0
};

View

跟MVC/MVP不同之是,MVVM中之View通过利用模板语法来声明式的拿数据渲染进DOM,当ViewModel对Model进行翻新的时,会经过数量绑定更新至View。写法如下:

<div id="myapp">
    <div>
        {{ val }}rmb
    </div>
    <div>
        <button v-on:click="sub(1)">-</button>
        <button v-on:click="add(1)">+</button>
    </div>
</div>

ViewModel

ViewModel大致上即是MVC的Controller和MVP的Presenter了,也是所有模式之重点,业务逻辑吗根本集中在此,其中的平等充分主导就是多少绑定,后面将会晤说话到。与MVP不同之凡,没有了View为Presente提供的接口,之前由Presenter负责的View和Model之间的数目并交付了ViewModel中之数码绑定进行处理,当Model发生变化,ViewModel就见面自动更新;ViewModel变化,Model也会更新。

new Vue({
    el: '#myapp',
    data: data,
    methods: {
        add(v) {
            if(this.val < 100) {
                this.val += v;
            }
        },
        sub(v) {
            if(this.val > 0) {
                this.val -= v;
            }
        }
    }
});

完整来拘禁,比MVC/MVP精简了成千上万,不仅仅简化了事情及界面的赖,还缓解了数频繁更新(以前用jQuery操作DOM很烦)的题材。因为于MVVM中,View不明了Model的存,ViewModel和Model也意识不交View,这种小耦合模式可以假设支付过程越是爱,提高利用之只是重用性。

数绑定

双向数据绑定,可以略而休恰当地理解也一个模板引擎,但是会根据数量变更实时渲染。——《界面之下:还原真实的MV*模式》

 

图片 6

 

以Vue中,使用了双向绑定技术(Two-Way-Data-Binding),就是View的转会实时让Model发生变化,而Model的别吧能实时更新至View。

“据说这游戏意儿可以申请专利呢”

 

图片 7

 

不等之MVVM框架中,实现双向数据绑定的技艺有所不同。目前片主流的前端框架实现数量绑定的方法大概有以下几种:

  • 数码劫持 (Vue)
  • 颁发-订阅模式 (Knockout、Backbone)
  • 脏值检查 (Angular)

我们这里要讲说Vue。

Vue采用数据劫持&发布-订阅模式之法,通过ES5提供的 Object.defineProperty() 方法来劫持(监控)各属性之 getter 、setter ,并于数(对象)发生变更时通订阅者,触发相应的监听回调。并且,由于是以不同之数量上触同步,可以精确的用变更发送给绑定的视图,而非是针对所有的数码都推行同一不成检测。要落实Vue中的双向数据绑定,大致可分开三只模块:Observer、Compile、Watcher,如图:

 

图片 8

 

  • Observer 数据监听器
    承担对数码对象的具备属性进行监听(数据劫持),监听到数码发生变化后通报订阅者。

  • Compiler 指令解析器
    环顾模板,并对准指令展开辨析,然后绑定指定事件。

  • Watcher 订阅者
    关联Observer和Compile,能够订阅并接收属性变动的通,执行令绑定的对应操作,更新视图。Update()是它们本身之一个方式,用于实践Compile中绑定的回调,更新视图。

数量劫持

一般针对数码的绑架都是经Object.defineProperty方法开展的,Vue中对应的函数为 defineReactive ,其日常对象的绑架的精简版代码如下:

var foo = {
  name: 'vue',
  version: '2.0'
}

function observe(data) {
    if (!data || typeof data !== 'object') {
        return
    }
    // 使用递归劫持对象属性
    Object.keys(data).forEach(function(key) {
        defineReactive(data, key, data[key]);
    })
}

function defineReactive(obj, key, value) {
     // 监听子属性 比如这里data对象里的 'name' 或者 'version'
     observe(value)

    Object.defineProperty(obj, key, {
        get: function reactiveGetter() {
            return value
        },
        set: function reactiveSetter(newVal) {
            if (value === newVal) {
                return
            } else {
                value = newVal
                console.log(`监听成功:${value} --> ${newVal}`)
            }
        }
    })
}

observe(foo)
foo.name = 'angular' // “监听成功:vue --> angular”

 

方就了针对性数码对象的监听,接下还待以监听到变化后去通知订阅者,这亟需贯彻一个音讯订阅器 Dep ,Watcher通过 Dep 添加订阅者,当数变动就触发 Dep.notify() ,Watcher调用好的 update() 方法成功视图更新。

写着形容着发现相差主题更加远了。。。数据劫持就先行开口这么多吧~对于想深入vue.js的校友可以参考勾三股四的Vue.js
源码学习笔记

总结

MV*的目的是管应用程序的多寡、业务逻辑与界面就三片解耦,分离关注点,不仅方便团队合作与测试,更便利甩锅维护及管制。业务逻辑不再关心底层数据的读写,而这些多少而因目标的形式展现给工作逻辑层。从
MVC –> MVP –>
MVVM,就如一个打怪升级的历程,它们都是以MVC的底子及就时代和应用环境的前行演变而来之。

每当我们纠结于采用啊架构模式要框架的时,不如先了解它们。静下想事情场景和开需要,不同要求下会有极度适合之化解方案。我们下此框架就意味着认同其的构思,相信其能够提升开发效率解决当前之题目,而不光是坐大家还当拟。

有人对新技巧乐此不疲,有人对新技巧不屑一顾。正使狄更斯以《双城记》中写的:

立即是不过好的时代,这是无比特别之时日,这是聪明的一时,这是愚昧的一代;这是奉的一世,这是怀疑的期;这是美好的时,这是黑暗的季节;这是期望之情,这是失望的冬;人们面前应有尽有,人们眼前一无所有;人们正直登天堂;人们在直下地狱。

告保持同样粒拥抱变化的衷心,在新技巧面前不盲目,不临旧。

 

有些参照资源:
GUI
Architectures
界面之下:还原真实的MV*模式
前端MVC变形记
深切了解JavaScript系列
250执行实现一个大概的MVVM

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website