javascript设计模式【下】

参考《javascript设计模式》[美]Addy Osmani一书,下面介绍使用javascript经常会使用的主要设计模式。本博文是使用ES5语法的【下】篇,还有一个【上】篇,ES6语法会单独写个博客。
主要是以下几个设计模式:

  • Constructor Pattern 构造模式
  • Module Pattern 模块化模式
  • Revealing Module Pattern 揭露模块化模式
  • Singleton Pattern 单例模式
  • Observer Pattern 观察者模式
  • Mediator Pattern 中介者模式
  • Prototype Pattern 原型模式
  • Command Pattern 命令行模式
  • Facade Pattern 外观模式
  • Factory Pattern 工厂模式
  • Mixin Pattern 混入模式
  • Decorator Pattern 装饰者模式
  • Flyweight Pattern 享元模式

所有代码挂在我的github上,包含有ES5和ES6语法实现的内容。
https://github.com/zrysmt/javascript-design-pattern

6.Facade Pattern 外观模式

外观模式也是只暴露一个很简单的方法,然后该方法在内部执行,调用内部的其他方法,jquery使用了很多这种模式,如 ().css .ajax()等

 var module = (function() {
     var _private = {
         i: 5,
         get: function() {
             console.log("current value:" + this.i);
         },
         set: function(val) {
             this.i = val;
         },
         run: function() {
             console.log("running");
         },
         jump: function() {
             console.log("jumping");
         }
     };
     return {
         facade: function(args) {
             _private.set(args.val);
             _private.get();
             if (args.run) {
                 _private.run();
             }
         }
     };
 }());
 // Outputs: "current value: 10" and "running"
 module.facade({ run: true, val: 10 });

7.Factory Pattern 工厂模式

怎么解释呢?工厂模式就是创建一个大型的制作工厂,然后其它的对象从这个工厂中产生。

//工厂
function VehicleFactory() {}
// Our default vehicleClass is Car 默认的是Car制造工厂
VehicleFactory.prototype.vehicleClass = Car;

VehicleFactory.prototype.createVehicle = function(options) {
    if (options.vehicleType === "car") {
        this.vehicleClass = Car;
    } else {
        this.vehicleClass = Truck;
    }
    return new this.vehicleClass(options);
};

两个具体的工厂里面的制作空间

function Car(options) {
    // some defaults
    this.doors = options.doors || 4;
    this.state = options.state || "brand new";
    this.color = options.color || "silver";
}
// A constructor for defining new trucks
function Truck(options) {
    this.state = options.state || "used";
    this.wheelSize = options.wheelSize || "large";
    this.color = options.color || "blue";
}

使用

var carFactory = new VehicleFactory();
var car = carFactory.createVehicle({
    vehicleType: "car",
    color: "yellow",
    doors: 6
});

console.log(car instanceof Car);// Outputs: true

8.Mixin Pattern 混入模式

简单解释下,混入就是将一个对象的方法复制给另外一个对象。

var Car = function(settings) {
    this.model = settings.model || "no model provided";
    this.color = settings.color || "no colour provided";
};

var Mixin = function() {};
Mixin.prototype = {
    driveForward: function() {
        console.log("drive forward");
    },
    driveBackward: function() {
        console.log("drive backward");
    },
    driveSideways: function() {
        console.log("drive sideways");
    }
};

function augment(receivingClass, givingClass) {
    if (arguments[2]) {
        for (var i = 2, len = arguments.length; i < len; i++) {
            receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
        }
    } else {
        for (var methodName in givingClass.prototype) {
            if (!Object.hasOwnProperty(receivingClass.prototype, methodName)) {
                receivingClass.prototype[methodName] = givingClass.prototype[methodName];
            }
        }
    }
}

// 只混入两个方法,Mixin的方法复制给Car
augment(Car, Mixin, "driveForward", "driveBackward");
// Create a new Car
var myCar = new Car({
    model: "Ford Escort",
    color: "blue"
});
myCar.driveForward();
myCar.driveBackward();

9.Decorator Pattern 装饰者模式

装饰模式是只针对一个基本的对象,添加一些修饰。如下面的是对MacBook,加内存(Memory函数装饰)增加75美元,雕刻(Engraving函数装饰)增加200美元,买保险(Insurance函数装饰)增加250美元。

function MacBook() {
    this.cost = function() {
        return 997; };
    this.screenSize = function() {
       return 11.6; };
}
// Decorator 1
function Memory(macbook) {
    var v = macbook.cost();
    macbook.cost = function() {
        return v + 75;
    };
}
// Decorator 2
function Engraving(macbook) {
    var v = macbook.cost();
    macbook.cost = function() {
        return v + 200;
    };
}
// Decorator 3
function Insurance(macbook) {
    var v = macbook.cost();
    macbook.cost = function() {
        return v + 250;
    };

}
var mb = new MacBook();
Memory(mb);
Engraving(mb);
Insurance(mb);

10.Flyweight Pattern 享元模式

享元模式我感觉就是共享一些数据或者方法,有一个工厂可以管理
* Flyweight
享元对象(类似于接口),提供的可以共享的属性/方法;
* Concrete Flyweight
具体享元对象,实现接口,具体实现享元对象的方法;
* Flyweight Factory
享元工厂对象,创建并管理flyweight对象

实现接口的方法,由于js没有,这里我们就模拟下。

//在js模拟存虚拟的继承,类似java中的implements
Function.prototype.implementsFor = function(parentClassOrObject) {
    if (parentClassOrObject.constructor === Function) {
        this.prototype = new parentClassOrObject();
        this.prototype.consturctor = this;
        this.prototype.parent = parentClassOrObject.prototype;
    }else {
        //纯虚拟继承
        this.prototype = parentClassOrObject;
        this.prototype.constructor = this;
        this.prototype.parent = parentClassOrObject;
    }
}
  • 享元对象
// Flyweight object 享元对象
var CoffeeOrder = {
    // Interfaces 接口
    serveCoffee: function(context) {},
    getFlavor: function() {}
};
  • 具体享元对象
// Implements CoffeeOrder
function CoffeeFlavor(newFlavor) {
    var flavor = newFlavor;
    if (typeof this.getFlavor === "function") {
        this.getFlavor = function() {
            return flavor;
        };
    }

    if (typeof this.serveCoffee === "function") {
        this.serveCoffee = function(context) {
            console.log("Serving Coffee flavor " + flavor + " to table number " + context.getTable());
        };
    }

}
// Implement interface for CoffeeOrder 实现接口
CoffeeFlavor.implementsFor(CoffeeOrder);
  • 辅助器
function CoffeeOrderContext(tableNumber) {
    return {
        getTable: function() {
            return tableNumber;
        }
    };
}
  • 享元工厂对象
//创建并管理flyweight对象
function CoffeeFlavorFactory() {
    var flavors = {},
        length = 0;

    return {
        getCoffeeFlavor: function(flavorName) {
            //这是个单例模式
            var flavor = flavors[flavorName];
            if (flavor === undefined) {
                flavor = new CoffeeFlavor(flavorName);//创建flyweight对象
                flavors[flavorName] = flavor;
                length++;
            }
            return flavor;
        },

        getTotalCoffeeFlavorsMade: function() {
            return length;
        }
    };
}
  • 测试
testFlyweight()

function testFlyweight() {
    // The flavors ordered. 已订购的flavors
    var flavors = new CoffeeFlavor(),
        // The tables for the orders. 
        tables = new CoffeeOrderContext(),
        // Number of orders made 订单数量
        ordersMade = 0,
        // The CoffeeFlavorFactory instance
        flavorFactory;
    //flavorIn 订单物的名称
    function takeOrders(flavorIn, table) {
        flavors[ordersMade] = flavorFactory.getCoffeeFlavor(flavorIn);
        //flavorFactory管理者创建好后(管理者也做了处理)返回给CoffeeFlavor
        tables[ordersMade++] = new CoffeeOrderContext(table);
    }

    flavorFactory = new CoffeeFlavorFactory();

    takeOrders("Cappuccino", 2);
    takeOrders("Cappuccino", 2);
    takeOrders("Frappe", 1);
    takeOrders("Frappe", 1);
    takeOrders("Xpresso", 1);
    takeOrders("Frappe", 897);
    takeOrders("Cappuccino", 97);
    takeOrders("Cappuccino", 97);
    takeOrders("Frappe", 3);
    takeOrders("Xpresso", 3);
    takeOrders("Cappuccino", 3);
    takeOrders("Xpresso", 96);
    takeOrders("Frappe", 552);
    takeOrders("Cappuccino", 121);
    takeOrders("Xpresso", 121);

    for (var i = 0; i < ordersMade; ++i) {
        flavors[i].serveCoffee(tables[i]);
    }
    console.log(" ");
    console.log("total CoffeeFlavor objects made: " + flavorFactory.getTotalCoffeeFlavorsMade());
}

所有代码挂在我的github上,包含有ES5和ES6语法实现的内容。
https://github.com/zrysmt/javascript-design-pattern

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 简介   模式   JavaScript:基本概念   ECMAScript 5   JSLint   Console   第2章 基本技巧   编写可维护的代码   尽量少用全局变量   for循环   for-in循环   不要增加内置的原型   SWitch模式   避免使用隐式类型转换   使用parseInt()的数值约定   编码约定   命名约定   编写注释   编写API文档   编写可读性强的代码   同行互查   在正式发布时精简代码   运行JSLint   小结   第3章 字面量和构造函数   对象字面量   自定义构造函数   强制使用new的模式   数组字面量   JSON   正则表达式字面量   基本值类型包装器   错误对象   小结   第4章 函数   背景   回调模式   返回函数   自定义函数   即时函数   即时对象初始化   初始化时分支   函数属性——备忘模式   配置对象   Curry   小结   第5章 对象创建模式   命名空间模式   声明依赖关系   私有属性和方法   模块模式   沙箱模式   静态成员   对象常量   链模式   method()方法   小结   第6章 代码复用模式   传统与现代继承模式的比较   使用类式继承时的预期结果   类式继承模式#1——默认模式   类式继承模式#2——借用构造函数   类式继承模式#3——借用和设置原型   类式继承模式#4——共享原型   类式继承模式#5——临时构造函数   Klass   原型继承   通过复制属性实现继承   借用方法   小结   第7章 设计模式   单体模式   工厂模式   迭代器模式   装饰者模式   策略模式   外观模式   代理模式   中介者模式   观察者模式   小结   第8章 DOM和浏览器模式   关注分离   DOM脚本   事件   长期运行脚本   远程脚本   配置JavaScript   载入策略

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值