设计模式

在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。

这是在《设计模式》一书中对设计模式的定义。在软件开发过程中,我们可能会遇到过这样的情况,我们现在发现一个问题,和以前的某个问题很相似,几乎可以用统一套解决方案,而且我们还发现,在某个条件下,这个解决方案几乎就是通用的,于是我们决定给解决类似问题的解决方案取一个统一的名字,这就是设计模式。

设计模式的意义

我们都知道无论在哪个行业经验都很重要,而经验的意义也就在于,当我们遇见一个以前遇见过的问题的时候,会自燃的想到以前是怎么解决的。而模式则是经过大量的实际项目验证过的优秀的解决方案,当我们熟悉了模式,就可以在适当的环境下,条件反射式地自如地使用它们。

所有设计模式的实现抖遵循一条原则,即“找出程序中变化的地方,并将变化封装起来”。一个程序的设计总是可以分为可变的部分和不可变的部分。当我们找出可变的部分并把这些部分封装起来,那么剩下的就是不变和稳定的部分。这些不变和稳定的部分是非常容易复用的。这也就是设计模式为什么描写的是可复用面向对象软件基础的原因。

当我看到上面这段话的时候,我就决定要把设计模式要好好的学一学,烂代码到处可见,但是我们不应该让别人看到我们的代码后,觉得写的代码是烂代码,而上面这段话则精辟的总结了如何避免写出烂代码。

代理模式

简单实现

当我们不能或者不想直接访问某个对象或者方法,需要使用一个中间对象来访问这个对象的时候,就可以称之为代理模式。例如我们现在交电话费可以直接通过支付宝来支付,不用再去跑到营业厅支付。此时,支付宝平台实际就是一种代理,最后,它还是要把钱支付给电信公司。

var Money = function(amount) {
    this.amount = amount
};
var customer = {
    pay: function(target) {
        var money = new Money(50);
        target.receiveMoney(money.amount)
    }
}
var agent = {
    receiveMoney: function(amount) {
         mobileCompanies.receiveMoney(amount)
    }
}
var mobileCompanies = {
    receiveMoney: function(amount) {
        alert("缴费成功,您成功缴费"+amount+'元')
    }
} 
customer.pay(agent)  // 50

保护代理和虚拟代理

保护代理

通过中间的代理层我们可以过滤掉一些请求,比如可以校验用户的账户的有效性,对于一些无效的缴费请求可以直接在这里就过滤掉。这样的代理模式称之为保护代理,即控制对实体的访问频率,例如当我们有一个接口请求的数据量很大,访问量也很大的时候,可能就需要严格控制对这个接口的访问,但是同时我们又不想更改这个函数的代码,增加校验代码,这时就可以通过保护代理模式。

保护代理用于控制不同权限的对象对目标对象的访问。

虚拟代理

虚拟代理把一些开销很大的对象,延迟到真正需要它的时候才去创建。

虚拟代理实现图片与加载
当图片过大或者网络状况不佳的情况下,图片往往有一段时间是空白的,常用的解决方案是先用一个loaging占位,待图片加载完成的时候再把它填充到img节点里面。

var imageNode = (function(){
    var imgNode = document.createElement('img')
    document.getElementById('testImg').appendChild(node)
    return {
        setSrc: function(src) {
            imgNode.src =  src
        }
    }
})()
var agent = (function(){
    vat image = new Image()
    image.onLoad = function() {
        imageNode.setSrc(this.src)
    }
    return {
        setSrc: function(src) {
            imageNode.setSrc('C:/user/test.gif')
            img.src = src
        }
    }
})()
agent.setSrc('http://test.com/test.jpg')

代理的意义

根据单一指责原则,就一个类或则方法而言,应该仅有一个使它变化的原因。如果一个类或者方法承担了多项职责,不止意味着它变的很大,同时引起它变化的原因也会很多。比如上面的方法中,图片的预加载只是一种锦上添花的效果,如果有一天我们不再需要预加载的时候,我们不需要改变imgNode对象。所以代理即隔离了变化的部分,即预加载功能,又能在适当的时候调用,即加载完成,当然在代理中间还可以有很多其他的操作,正是如开头所说的,将变化的部分封装起来,将不变的地方抽取出来。

主要参考《JavaScript设计模式与开发实践》


wupengyu
1.8k 声望166 粉丝

写作是为了更好的思考