zoukankan      html  css  js  c++  java
  • 装饰者模式

    1.jquery $('.a').find('.b')  , $('.a') 以后返回一个对象, find('.b') 以后 也是返回一个对象,对$('.a')装饰一个方法 find , $('.a').find('.b') 再加一个装饰 width(); 返回的仍然是一个完整的jquery的对象

    这就是装饰者模式。

    参考书:[JavaScript模式].Stoyan.Stefanov  =》第153页

    所以可以初步理解为,一个对象,有很多方法,每次调用以后,任然返回一个完整的值被方法装饰过的对象。能实现这样的功能,就是装饰者模式。所以可以自己来实现一下。

    假设,有个对象 obj,修改它的长度为100,obj.changeLength(100), 再次计算它的平方根号
    为100*100. obj.changeLength(100).Math("sqr")或者 100+100 obj.changeLength(100).Math("add") ,(100+100)*(100 + 100)
    obj.changeLength(100).Math("add").Math('sqr') 返回结果。
    那么每次调用之后,返回的都是一个对象,要如何实现,这个对象的构造方法?

    function setObj(width){
            this.width = 100||width;
        }
        setObj.prototype.setWidth = function(){
            return this.width + 'px';
        }
    
        setObj.prototype.changeLength = function(width){
            this.width = width;
            return this;
        }
    
        setObj.prototype.Math = function(value){
            if(value == 'add'){
                this.width = this.width + this.width;
            }else if(value == 'sqr'){
                this.width = this.width * this.width;
            }
            return this;
        }
    
    
        var newobj = new setObj(120);
        console.log(newobj.changeLength(200).Math("add").Math("sqr").setWidth());
       console.log(newobj.changeLength(200).Math("add").setWidth());

    打印的 160000px 这样就能实现了,这样随便调用什么方法,都是返回的一个完整的对象。

    但是这样写有个问题,就是Math("add")方法实际框架中,可能会包含很多计算,修改很多值,所以嵌套在if里面无法维护。修改

    setObj.prototype.Math 不返回 this, 返回一个对 setObj 的继承,和方法的重写。不去改变初始参数this.width的值。
        function setObj(width){
            this.width = width||100;
        }
        setObj.prototype.getWidth = function(){
            return this.width;
        }
    
        setObj.prototype.changeLength = function(width){
            this.width = width;
            return this;
        }
        
        setObj.Maths = {};
        setObj.Maths.add = {
            getWidth: function() {
                console.log(this);
                return this.getWidth()+'%';
            }
        }
        
        setObj.Maths.sqr = {
            getWidth: function() {
                return this.getWidth()+'px';
            }
        }
    
        setObj.prototype.Math = function(value){
            var F = function(){};
            var overObj = this.constructor.Maths[value];
            F.prototype = this; // F构造函数继承setObj
            var newObj = new F();
            
            for(var i in overObj){
                console.log(i);
                if(overObj.hasOwnProperty(i)){
                    newObj[i] = overObj[i];
                }
            }
            return newObj;
        }
    
    
        var newobj = new setObj(120);
        console.log(newobj.Math("add"));

    这样写完以后,就会出现一个问题,

    getWidth 不停的回调 自己。死循环了,所以找一个变量寄存一下原来的 getWidth方法
     
    function setObj(width){
            this.width = width||100;
        }
        setObj.prototype.getWidth = function(){
            return this.width;
        }
    
        setObj.prototype.changeLength = function(width){
            this.width = width;
            return this;
        }
        
        setObj.Maths = {};
        setObj.Maths.add = {
            getWidth: function() {
                return this.uber.getWidth() + this.uber.getWidth();
            }
        }
        
        setObj.Maths.sqr = {
            getWidth: function() {
                return this.uber.getWidth() * this.uber.getWidth();
            }
        }
    
        setObj.prototype.Math = function(value){
            var F = function(){};
            var overObj = this.constructor.Maths[value];
            F.prototype = this; // F构造函数继承setObj
            var newObj = new F();
            newObj.uber = F.prototype;
            
            for(var i in overObj){
                if(overObj.hasOwnProperty(i)){
                    newObj[i] = overObj[i];
                }
            }
            return newObj;
        }
    
    
        var newobj = new setObj(120);
        console.log(newobj.Math("add").Math("sqr").getWidth());

    看一下官方案列

    function Sale(price){
            this.price = price || 100;
        }
    
        Sale.prototype.getPrice = function(){
            return this.price;
        }
    
        Sale.decorators = {};
    
        Sale.decorators.fedtax = {
            getPrice: function(){
                var price = this.uber.getPrice();
                price += price *7.5 / 100;
                return price;
            }
        }
    
        Sale.decorators.money = { //把方法挂在在构造函数上面,这样这个方法就属于这个构造里面
            getPrice: function() {
                return "$" + this.uber.getPrice().toFixed(2);
            }
        }
    
        Sale.decorators.cdn = {
            getPrice: function() {
                return "CDN$" + this.uber.getPrice().toFixed(2);
            }
        }
    
        Sale.prototype.decorate = function(decorator){
            var F = function(){},
                overrides = this.constructor.decorators[decorator],
                i, newobj;
            F.prototype = this;
            newobj = new F();
            newobj.uber = F.prototype; //newobj拥有了F对象的所有方法
            for(i in overrides){
                if(overrides.hasOwnProperty(i)){ //重写getPrice方法
                    newobj[i] = overrides[i];
                }
            }
            return newobj;
        }
    
        var sale = new Sale(100);
        var back = sale.decorate("fedtax").decorate("money");

    看一下jquery里面是怎么使用的

    无论调用什么,返回的都是

  • 相关阅读:
    如何多个router 进行合并?
    钉钉微应用开发
    vscode 常用命令行
    window.location.search 为何在url 带# 号时获取不到 ?
    如何在嵌套的app中运用vue去写单页面H5
    两秒内不能重复点击
    linux系统下安装dubbo-admin
    二、SpringBoot实现上传文件到fastDFS文件服务器
    一、手把手教你docker搭建fastDFS文件上传下载服务器
    idea中git远程版本回退
  • 原文地址:https://www.cnblogs.com/chenyi4/p/13471079.html
Copyright © 2011-2022 走看看