├── Command
├── Command-ES6.js
├── Command.js
├── index-ES6.html
└── index.html
├── Constructor
├── Constructor.js
└── index.html
├── Decorator
├── Decorator-ES6.js
├── Decorator.js
├── index-ES6.html
└── index.html
├── Facade
├── Facade-ES6.js
├── Facade.js
└── index-ES6.html
├── Factory
├── Factory-ES6.js
├── Factory.js
├── index-ES6.html
└── index.html
├── Flyweight
├── Flyweight-ES6.js
├── Flyweight.js
├── flyweight-in-jquery.html
└── index.html
├── Mediator
└── Mediator.js
├── Mixin
├── Mixin-ES6.js
├── Mixin.js
├── index-ES6.html
└── index.html
├── Module
├── Module-ES6.js
├── Module.js
├── index.html
└── module-in-jquery.html
├── Observer
├── Observer-ES6.js
├── Observer.js
├── Publish-Subscribe-ES6.js
├── Publish-Subscribe.js
├── index.html
└── publish-subcribe.html
├── README.md
├── Revealing
├── Revealing.js
└── index.html
├── Singleton
├── SingLeton.js
├── Singleton-ES6.js
└── index.html
└── jqueryPlugin
├── Lightweight-Start.js
├── WidgetFactory.js
└── index.html
/Command/Command-ES6.js:
--------------------------------------------------------------------------------
1 | //命令行模式
2 | class CarManager {
3 | requestInfo(model, id) {
4 | return "The information for " + model + " with ID " + id + " is foobar";
5 | }
6 |
7 | // purchase the car
8 | buyVehicle(model, id) {
9 | return "You have successfully purchased Item " + id + ", a " + model;
10 | }
11 |
12 | // arrange a viewing
13 | arrangeViewing(model, id) {
14 | return "You have successfully booked a viewing of " + model + " ( " + id + ") ";
15 | }
16 | execute(name) {
17 | let carManager = new CarManager();
18 | return carManager[name] && carManager[name].apply(carManager, [].slice.call(arguments, 1));
19 | }
20 | }
21 |
22 | let carManager = new CarManager();
23 |
24 | console.log(carManager.execute("arrangeViewing", "Ferrari", "14523"));
25 |
26 | console.log(carManager.execute("requestInfo", "Ford Mondeo", "54323"));
27 |
28 | console.log(carManager.execute("requestInfo", "Ford Escort", "34232"));
29 |
--------------------------------------------------------------------------------
/Command/Command.js:
--------------------------------------------------------------------------------
1 | //命令行模式
2 |
3 | (function() {
4 | var CarManager = {
5 | // request information
6 | requestInfo: function(model, id) {
7 | return "The information for " + model + " with ID " + id + " is foobar";
8 | },
9 |
10 | // purchase the car
11 | buyVehicle: function(model, id) {
12 | return "You have successfully purchased Item " + id + ", a " + model;
13 | },
14 |
15 | // arrange a viewing
16 | arrangeViewing: function(model, id) {
17 | return "You have successfully booked a viewing of " + model + " ( " + id + ") ";
18 | }
19 |
20 | };
21 |
22 | CarManager.execute = function(name) {
23 | return CarManager[name] && CarManager[name].apply(CarManager, [].slice.call(arguments, 1));
24 | };
25 |
26 | console.log(CarManager.execute("arrangeViewing", "Ferrari", "14523"));
27 | console.log(CarManager.execute("requestInfo", "Ford Mondeo", "54323"));
28 | console.log(CarManager.execute("requestInfo", "Ford Escort", "34232"));
29 | console.log(CarManager.execute("buyVehicle", "Ford Escort", "34232"));
30 | })();
31 |
--------------------------------------------------------------------------------
/Command/index-ES6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Command/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Constructor/Constructor.js:
--------------------------------------------------------------------------------
1 | //构造器模式
2 |
3 | //==============================================================================
4 | // Each of the following options will create a new empty object:
5 | // 构造空对象
6 | var newObject = {};
7 | // or
8 | var newObject = Object.create(null);
9 | // or
10 | var newObject = new Object();
11 |
12 | /******************ES 3******************************/
13 | // 1. Dot syntax
14 |
15 | // Set properties
16 | newObject.someKey = "Hello World";
17 | // Get properties
18 | var key = newObject.someKey;
19 |
20 | // 2. Square bracket syntax
21 |
22 | // Set properties
23 | newObject["someKey"] = "Hello World";
24 | // Get properties
25 | var key = newObject["someKey"];
26 |
27 | /******************ES 5******************************/
28 | // 3.Object.defineProperty
29 | Object.defineProperty(newObject, "someKey", {
30 | value: "for more control of the property's behavior",
31 | wirtable: true,
32 | enumerable: true,
33 | configurable: true
34 | });
35 |
36 | // 4.Object.defineProperties
37 | // 设置属性
38 | Object.defineProperties(newObject, {
39 | "someKey": {
40 | value: "Hello World",
41 | writable: true
42 | },
43 | "anotherKey": {
44 | value: "Foo bar",
45 | writable: false
46 | }
47 | });
48 |
49 |
50 | console.log(newObject);
51 | //==============================================================================
52 | // 1.基本的Constructor
53 | function Car(model, year, miles) {
54 | this.model = model;
55 | this.year = year;
56 | this.miles = miles;
57 |
58 | this.toString = function() {
59 | return this.model + " has done " + this.miles + " miles";
60 | };
61 | }
62 | // Usage:
63 | // We can create new instances of the car
64 | var civic = new Car("Honda Civic", 2009, 20000);
65 | var mondeo = new Car("Ford Mondeo", 2010, 5000);
66 |
67 | console.log(civic.toString());
68 | console.log(mondeo.toString());
69 | //继承比较困难
70 |
71 | // 2.带原型的Constructor
72 | function Car1(model, year, miles) {
73 | this.model = model;
74 | this.year = year;
75 | this.miles = miles;
76 | }
77 |
78 | // Note here that we are using Object.prototype.newMethod rather than
79 | // Object.prototype so as to avoid redefining the prototype object
80 | Car1.prototype.toString = function() {
81 | return this.model + " has done " + this.miles + " miles";
82 | };
83 | // Usage:
84 | var civic = new Car1( "Honda Civic", 2009, 20000 );
85 | var mondeo = new Car1( "Ford Mondeo", 2010, 5000 );
86 | console.log( civic.toString() );
87 | console.log( mondeo.toString() );
88 |
89 |
--------------------------------------------------------------------------------
/Constructor/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Decorator/Decorator-ES6.js:
--------------------------------------------------------------------------------
1 | //装饰者模式
2 |
3 | class MacBook {
4 | cost() {
5 | return 997;
6 | }
7 | screenSize() {
8 | return 11.6;
9 | }
10 | }
11 |
12 | function Memory(macbook) {
13 |
14 | let v = macbook.cost();
15 | macbook.cost = function() {
16 | return v + 75;
17 | };
18 |
19 | }
20 |
21 | // Decorator 2
22 | function Engraving(macbook) {
23 |
24 | let v = macbook.cost();
25 | macbook.cost = function() {
26 | return v + 200;
27 | };
28 |
29 | }
30 |
31 | // Decorator 3
32 | function Insurance(macbook) {
33 |
34 | let v = macbook.cost();
35 | macbook.cost = function() {
36 | return v + 250;
37 | };
38 |
39 | }
40 |
41 | let mb = new MacBook();
42 | Memory(mb);
43 | Engraving(mb);
44 | Insurance(mb);
45 |
46 | // Outputs: 1522
47 | console.log(mb.cost());
48 | // Outputs: 11.6
49 | console.log(mb.screenSize());
--------------------------------------------------------------------------------
/Decorator/Decorator.js:
--------------------------------------------------------------------------------
1 | //装饰者模式
2 |
3 | // A vehicle constructor
4 | function vehicle(vehicleType) {
5 |
6 | // some sane defaults
7 | this.vehicleType = vehicleType || "car";
8 | this.model = "default";
9 | this.license = "00000‐000";
10 |
11 | }
12 |
13 | // Test instance for a basic vehicle
14 | var testInstance = new vehicle("car");
15 | console.log(testInstance);
16 |
17 | // Outputs:
18 | // vehicle: car, model:default, license: 00000‐000
19 |
20 | // Lets create a new instance of vehicle, to be decorated
21 | var truck = new vehicle("truck");
22 |
23 | // New functionality we're decorating vehicle with
24 | truck.setModel = function(modelName) {
25 | this.model = modelName;
26 | };
27 |
28 | truck.setColor = function(color) {
29 | this.color = color;
30 | };
31 |
32 | // Test the value setters and value assignment works correctly
33 | truck.setModel("CAT");
34 | truck.setColor("blue");
35 |
36 | console.log(truck);
37 |
38 | // Outputs:
39 | // vehicle:truck, model:CAT, color: blue
40 |
41 | // Demonstrate "vehicle" is still unaltered
42 | var secondInstance = new vehicle("car");
43 | console.log(secondInstance);
44 |
45 | // Outputs:
46 | // vehicle: car, model:default, license: 00000‐000
47 |
48 | //=====================================================================
49 | console.log("===================================");
50 | // The constructor to decorate
51 | function MacBook() {
52 |
53 | this.cost = function() {
54 | return 997; };
55 | this.screenSize = function() {
56 | return 11.6; };
57 |
58 | }
59 |
60 | // Decorator 1
61 | function Memory(macbook) {
62 |
63 | var v = macbook.cost();
64 | macbook.cost = function() {
65 | return v + 75;
66 | };
67 |
68 | }
69 |
70 | // Decorator 2
71 | function Engraving(macbook) {
72 |
73 | var v = macbook.cost();
74 | macbook.cost = function() {
75 | return v + 200;
76 | };
77 |
78 | }
79 |
80 | // Decorator 3
81 | function Insurance(macbook) {
82 |
83 | var v = macbook.cost();
84 | macbook.cost = function() {
85 | return v + 250;
86 | };
87 |
88 | }
89 |
90 | var mb = new MacBook();
91 | Memory(mb);
92 | Engraving(mb);
93 | Insurance(mb);
94 |
95 | // Outputs: 1522
96 | console.log(mb.cost());
97 |
98 | // Outputs: 11.6
99 | console.log(mb.screenSize());
100 |
--------------------------------------------------------------------------------
/Decorator/index-ES6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Decorator/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Facade/Facade-ES6.js:
--------------------------------------------------------------------------------
1 | //装饰者模式
2 | class Facade {
3 | _get() {
4 | console.log("current value:" + this.i);
5 | }
6 | _set(val) {
7 | this.i = val;
8 | }
9 | _run() {
10 | console.log("running");
11 | }
12 | _jump() {
13 | console.log("jumping");
14 | }
15 |
16 | facade(args) {
17 | this._set(args.val);
18 | this._get();
19 | if (args._run) {
20 | this._run();
21 | }
22 | }
23 | }
24 |
25 | let fa = new Facade();
26 | fa.facade({ run: true, val: 10 });
27 |
--------------------------------------------------------------------------------
/Facade/Facade.js:
--------------------------------------------------------------------------------
1 | var module = (function() {
2 |
3 | var _private = {
4 | i: 5,
5 | get: function() {
6 | console.log("current value:" + this.i);
7 | },
8 | set: function(val) {
9 | this.i = val;
10 | },
11 | run: function() {
12 | console.log("running");
13 | },
14 | jump: function() {
15 | console.log("jumping");
16 | }
17 | };
18 |
19 | return {
20 |
21 | facade: function(args) {
22 | _private.set(args.val);
23 | _private.get();
24 | if (args.run) {
25 | _private.run();
26 | }
27 | }
28 | };
29 | }());
30 |
31 |
32 | // Outputs: "current value: 10" and "running"
33 | module.facade({ run: true, val: 10 });
34 |
--------------------------------------------------------------------------------
/Facade/index-ES6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Facade
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Factory/Factory-ES6.js:
--------------------------------------------------------------------------------
1 | //工厂模式使用ES6实现
2 |
3 | //工厂
4 | class VehicleFactory {
5 | constructor() {
6 | this.vehicleClass = Car;
7 | }
8 | createVehicle(options) {
9 | if (options.vehicleType === "car") {
10 | this.vehicleClass = Car;
11 | } else {
12 | this.vehicleClass = Truck;
13 | }
14 | return new this.vehicleClass(options);
15 | }
16 | }
17 |
18 | class Car {
19 | constructor(options) {
20 | // some defaults
21 | options = options || "";
22 | this.doors = options.doors || 4;
23 | this.state = options.state || "brand new";
24 | this.color = options.color || "silver";
25 | }
26 | }
27 |
28 |
29 | class Truck {
30 | constructor(options) {
31 | this.state = options.state || "used";
32 | this.wheelSize = options.wheelSize || "large";
33 | this.color = options.color || "blue";
34 | }
35 | }
36 |
37 | //usage
38 | let carFactory = new VehicleFactory();
39 | let car = carFactory.createVehicle({
40 | vehicleType: "car",
41 | color: "yellow",
42 | doors: 6
43 | });
44 |
45 | // Test to confirm our car was created using the vehicleClass/prototype Car
46 |
47 | // Outputs: true
48 | console.log(car instanceof Car);
49 |
50 | // Outputs: Car object of color "yellow", doors: 6 in a "brand new" state
51 | console.log(car);
52 |
53 |
54 |
55 | //===================================================================
56 | //抽象工厂
57 | class AbstractVehicleFactory {
58 | constructor() {
59 | this.types = {}; //存储对象
60 | }
61 | getVehicle(type, customizations) {
62 | let Vehicle = this.types[type];
63 | return (Vehicle ? new Vehicle(customizations) : null);
64 | }
65 |
66 | registerVehicle(type, Vehicle) {
67 | let proto = Vehicle.prototype;
68 | // only register classes that fulfill the vehicle contract
69 | // if (proto.drive && proto.breakDown) {
70 | this.types[type] = Vehicle;
71 | // }
72 |
73 | return AbstractVehicleFactory;
74 | }
75 | }
76 | let abstractVehicleFactory = new AbstractVehicleFactory();
77 |
78 | abstractVehicleFactory.registerVehicle("car", Car);
79 | abstractVehicleFactory.registerVehicle("truck", Truck);
80 |
81 | // Instantiate a new car based on the abstract vehicle type
82 | var car2 = abstractVehicleFactory.getVehicle("car", {
83 | color: "lime green",
84 | state: "like new"
85 | });
86 |
87 | // Instantiate a new truck in a similar manner
88 | var truck2 = abstractVehicleFactory.getVehicle("truck", {
89 | wheelSize: "medium",
90 | color: "neon yellow"
91 | });
92 |
93 |
94 |
95 | console.log(car2,truck2);
96 |
97 | console.log(abstractVehicleFactory);
98 | console.log(Object.getPrototypeOf(abstractVehicleFactory));
--------------------------------------------------------------------------------
/Factory/Factory.js:
--------------------------------------------------------------------------------
1 | // 工厂模式
2 | // Types.js ‐ Constructors used behind the scenes
3 |
4 | // A constructor for defining new cars
5 | function Car(options) {
6 | // some defaults
7 | this.doors = options.doors || 4;
8 | this.state = options.state || "brand new";
9 | this.color = options.color || "silver";
10 |
11 | }
12 |
13 | // A constructor for defining new trucks
14 | function Truck(options) {
15 | this.state = options.state || "used";
16 | this.wheelSize = options.wheelSize || "large";
17 | this.color = options.color || "blue";
18 | }
19 |
20 |
21 | // FactoryExample.js
22 |
23 | // Define a skeleton vehicle factory
24 | function VehicleFactory() {}
25 |
26 | // Define the prototypes and utilities for this factory
27 |
28 | // Our default vehicleClass is Car
29 | VehicleFactory.prototype.vehicleClass = Car;
30 |
31 | // Our Factory method for creating new Vehicle instances
32 | VehicleFactory.prototype.createVehicle = function(options) {
33 |
34 | if (options.vehicleType === "car") {
35 | this.vehicleClass = Car;
36 | } else {
37 | this.vehicleClass = Truck;
38 | }
39 |
40 | return new this.vehicleClass(options);
41 |
42 | };
43 |
44 | // Create an instance of our factory that makes cars
45 | var carFactory = new VehicleFactory();
46 | var car = carFactory.createVehicle({
47 | vehicleType: "car",
48 | color: "yellow",
49 | doors: 6
50 | });
51 |
52 | // Test to confirm our car was created using the vehicleClass/prototype Car
53 |
54 | // Outputs: true
55 | console.log(car instanceof Car);
56 |
57 | // Outputs: Car object of color "yellow", doors: 6 in a "brand new" state
58 | console.log(car);
59 |
60 |
61 | //================================================================================
62 | //抽象工厂
63 | var AbstractVehicleFactory = (function() {
64 |
65 | // Storage for our vehicle types
66 | var types = {};
67 |
68 | return {
69 | getVehicle: function(type, customizations) {
70 | var Vehicle = types[type];
71 | return (Vehicle ? new Vehicle(customizations) : null);
72 | },
73 |
74 | registerVehicle: function(type, Vehicle) {
75 | var proto = Vehicle.prototype;
76 | // only register classes that fulfill the vehicle contract
77 | if (proto.drive && proto.breakDown) {
78 | types[type] = Vehicle;
79 | }
80 |
81 | return AbstractVehicleFactory;
82 | }
83 | };
84 | })();
85 |
86 | Car.prototype.drive = function(){}
87 | Truck.prototype.drive = function(){}
88 | Car.prototype.breakDown = function(){}
89 | Truck.prototype.breakDown = function(){}
90 |
91 | // Usage:
92 |
93 | AbstractVehicleFactory.registerVehicle("car", Car);
94 | AbstractVehicleFactory.registerVehicle("truck", Truck);
95 |
96 | // Instantiate a new car based on the abstract vehicle type
97 | var car2 = AbstractVehicleFactory.getVehicle("car", {
98 | color: "lime green",
99 | state: "like new"
100 | });
101 |
102 | // Instantiate a new truck in a similar manner
103 | var truck2 = AbstractVehicleFactory.getVehicle("truck", {
104 | wheelSize: "medium",
105 | color: "neon yellow"
106 | });
107 |
108 | console.log(car2,truck2);
--------------------------------------------------------------------------------
/Factory/index-ES6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Factory/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Flyweight/Flyweight-ES6.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrysmt/javascript-design-pattern/ecb4288cb8bce7b4ba00dd4bd56f5d36e3971085/Flyweight/Flyweight-ES6.js
--------------------------------------------------------------------------------
/Flyweight/Flyweight.js:
--------------------------------------------------------------------------------
1 | //享元模式
2 |
3 | //在js模拟存虚拟的继承,类似java中的implements
4 | Function.prototype.implementsFor = function(parentClassOrObject) {
5 | if (parentClassOrObject.constructor === Function) {
6 | this.prototype = new parentClassOrObject();
7 | this.prototype.consturctor = this;
8 | this.prototype.parent = parentClassOrObject.prototype;
9 | }else {
10 | //纯虚拟继承
11 | this.prototype = parentClassOrObject;
12 | this.prototype.constructor = this;
13 | this.prototype.parent = parentClassOrObject;
14 | }
15 | }
16 |
17 | // Flyweight object 享元对象
18 | var CoffeeOrder = {
19 | // Interfaces 接口
20 | serveCoffee: function(context) {},
21 | getFlavor: function() {}
22 | };
23 |
24 |
25 | // ConcreteFlyweight object that creates ConcreteFlyweight 具体享元对象
26 | // Implements CoffeeOrder
27 | function CoffeeFlavor(newFlavor) {
28 |
29 | var flavor = newFlavor;
30 |
31 | // If an interface has been defined for a feature
32 | // implement the feature
33 | if (typeof this.getFlavor === "function") {
34 | this.getFlavor = function() {
35 | return flavor;
36 | };
37 | }
38 |
39 | if (typeof this.serveCoffee === "function") {
40 | this.serveCoffee = function(context) {
41 | console.log("Serving Coffee flavor " + flavor + " to table number " + context.getTable());
42 | };
43 | }
44 |
45 | }
46 |
47 |
48 | // Implement interface for CoffeeOrder 实现接口
49 | CoffeeFlavor.implementsFor(CoffeeOrder);
50 |
51 |
52 | // Handle table numbers for a coffee order
53 | // tableNumber 订单数 辅助器
54 | function CoffeeOrderContext(tableNumber) {
55 | return {
56 | getTable: function() {
57 | return tableNumber;
58 | }
59 | };
60 | }
61 |
62 | //享元工厂对象
63 | //创建并管理flyweight对象
64 | function CoffeeFlavorFactory() {
65 | var flavors = {},
66 | length = 0;
67 |
68 | return {
69 | getCoffeeFlavor: function(flavorName) {
70 | //这是个单例模式
71 | var flavor = flavors[flavorName];
72 | if (flavor === undefined) {
73 | flavor = new CoffeeFlavor(flavorName);//创建flyweight对象
74 | flavors[flavorName] = flavor;
75 | length++;
76 | }
77 | return flavor;
78 | },
79 |
80 | getTotalCoffeeFlavorsMade: function() {
81 | return length;
82 | }
83 | };
84 | }
85 |
86 | // Sample usage: 测试
87 | testFlyweight()
88 |
89 | function testFlyweight() {
90 | // The flavors ordered. 已订购的flavors
91 | var flavors = new CoffeeFlavor(),
92 | // The tables for the orders.
93 | tables = new CoffeeOrderContext(),
94 | // Number of orders made 订单数量
95 | ordersMade = 0,
96 | // The CoffeeFlavorFactory instance
97 | flavorFactory;
98 | //flavorIn 订单物的名称
99 | function takeOrders(flavorIn, table) {
100 | flavors[ordersMade] = flavorFactory.getCoffeeFlavor(flavorIn);
101 | //flavorFactory管理者创建好后(管理者也做了处理)返回给CoffeeFlavor
102 | tables[ordersMade++] = new CoffeeOrderContext(table);
103 | }
104 |
105 | flavorFactory = new CoffeeFlavorFactory();
106 |
107 | takeOrders("Cappuccino", 2);
108 | takeOrders("Cappuccino", 2);
109 | takeOrders("Frappe", 1);
110 | takeOrders("Frappe", 1);
111 | takeOrders("Xpresso", 1);
112 | takeOrders("Frappe", 897);
113 | takeOrders("Cappuccino", 97);
114 | takeOrders("Cappuccino", 97);
115 | takeOrders("Frappe", 3);
116 | takeOrders("Xpresso", 3);
117 | takeOrders("Cappuccino", 3);
118 | takeOrders("Xpresso", 96);
119 | takeOrders("Frappe", 552);
120 | takeOrders("Cappuccino", 121);
121 | takeOrders("Xpresso", 121);
122 |
123 | for (var i = 0; i < ordersMade; ++i) {
124 | flavors[i].serveCoffee(tables[i]);
125 | }
126 | console.log(" ");
127 | console.log("total CoffeeFlavor objects made: " + flavorFactory.getTotalCoffeeFlavorsMade());
128 | }
129 |
--------------------------------------------------------------------------------
/Flyweight/flyweight-in-jquery.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 | click me
11 | hello
12 |
13 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Flyweight/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Mediator/Mediator.js:
--------------------------------------------------------------------------------
1 | //中介者模式
2 | //类似观察者模式
3 |
4 | var mediator = (function() {
5 | // Storage for topics that can be broadcast or listened to
6 | var topics = {};
7 |
8 | // Subscribe to a topic, supply a callback to be executed
9 | // when that topic is broadcast to
10 | var subscribe = function(topic, fn) {
11 |
12 | if (!topics[topic]) {
13 | topics[topic] = [];
14 | }
15 |
16 | topics[topic].push({ context: this, callback: fn });
17 |
18 | return this;
19 | };
20 |
21 | // Publish/broadcast an event to the rest of the application
22 | var publish = function(topic) {
23 |
24 | var args;
25 |
26 | if (!topics[topic]) {
27 | return false;
28 | }
29 |
30 | args = Array.prototype.slice.call(arguments, 1);
31 | for (var i = 0, l = topics[topic].length; i < l; i++) {
32 |
33 | var subscription = topics[topic][i];
34 | subscription.callback.apply(subscription.context, args);
35 | }
36 | return this;
37 | };
38 |
39 | return {
40 | publish: publish,
41 | subscribe: subscribe,
42 | installTo: function(obj) {
43 | obj.subscribe = subscribe;
44 | obj.publish = publish;
45 | }
46 | };
47 |
48 | }());
49 |
--------------------------------------------------------------------------------
/Mixin/Mixin-ES6.js:
--------------------------------------------------------------------------------
1 | // 混入模式
2 | //http://es6.ruanyifeng.com/#docs/class#Mixin模式的实现
3 |
4 | function mix(...mixins) {
5 | class Mix {}
6 |
7 | for (let mixin of mixins) {
8 | copyProperties(Mix, mixin);
9 | copyProperties(Mix.prototype, mixin.prototype);
10 | }
11 |
12 | return Mix;
13 | }
14 |
15 | function copyProperties(target, source) {
16 | for (let key of Reflect.ownKeys(source)) {
17 | if ( key !== "constructor"
18 | && key !== "prototype"
19 | && key !== "name"
20 | ) {
21 | let desc = Object.getOwnPropertyDescriptor(source, key);
22 | Object.defineProperty(target, key, desc);
23 | }
24 | }
25 | }
26 |
27 | //使用-继承即可
28 | class DistributedEdit extends mix(Loggable, Serializable) {
29 | // ...
30 | }
--------------------------------------------------------------------------------
/Mixin/Mixin.js:
--------------------------------------------------------------------------------
1 | // 混入模式
2 | // Define a simple Car constructor
3 | var Car = function(settings) {
4 |
5 | this.model = settings.model || "no model provided";
6 | this.color = settings.color || "no colour provided";
7 |
8 | };
9 |
10 | // Mixin
11 | var Mixin = function() {};
12 |
13 | Mixin.prototype = {
14 |
15 | driveForward: function() {
16 | console.log("drive forward");
17 | },
18 |
19 | driveBackward: function() {
20 | console.log("drive backward");
21 | },
22 |
23 | driveSideways: function() {
24 | console.log("drive sideways");
25 | }
26 |
27 | };
28 |
29 |
30 | // Extend an existing object with a method from another
31 | function augment(receivingClass, givingClass) {
32 |
33 | // only provide certain methods
34 | if (arguments[2]) {
35 | for (var i = 2, len = arguments.length; i < len; i++) {
36 | receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
37 | }
38 | }
39 | // provide all methods
40 | else {
41 | for (var methodName in givingClass.prototype) {
42 |
43 | // check to make sure the receiving class doesn't
44 | // have a method of the same name as the one currently
45 | // being processed
46 | if (!Object.hasOwnProperty(receivingClass.prototype, methodName)) {
47 | receivingClass.prototype[methodName] = givingClass.prototype[methodName];
48 | }
49 |
50 | // Alternatively:
51 | // if ( !receivingClass.prototype[methodName] ) {
52 | // receivingClass.prototype[methodName] =givingClass.prototype[methodName];
53 | // }
54 | }
55 | }
56 | }
57 |
58 |
59 | // Augment the Car constructor to include "driveForward" and "driveBackward"
60 | // 只混入两个方法
61 | augment(Car, Mixin, "driveForward", "driveBackward");
62 |
63 | // Create a new Car
64 | var myCar = new Car({
65 | model: "Ford Escort",
66 | color: "blue"
67 | });
68 |
69 | // Test to make sure we now have access to the methods
70 | myCar.driveForward();
71 | myCar.driveBackward();
72 |
73 | // Outputs:
74 | // drive forward
75 | // drive backward
76 |
77 | // We can also augment Car to include all functions from our mixin
78 | // by not explicitly listing a selection of them
79 | augment(Car, Mixin);
80 |
81 | var mySportsCar = new Car({
82 | model: "Porsche",
83 | color: "red"
84 | });
85 | mySportsCar.driveSideways();
86 |
87 | // Outputs:
88 | // drive sideways
89 |
--------------------------------------------------------------------------------
/Mixin/index-ES6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Mixin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Module/Module-ES6.js:
--------------------------------------------------------------------------------
1 | function Module(container) {
2 | return new class {
3 | get container() {
4 | return container;
5 | }
6 |
7 | init() {
8 | this.container.innerHTML = 'ES6 module';
9 | }
10 | }
11 | }
12 |
13 | export default Module;
14 |
15 | /*********************************************************/
16 | let privateName = Symbol('privateName');//利用Symbol做成私有的变量
17 | //直接用class类
18 | class MyModule {
19 |
20 | set container(value) {
21 | this.value = value;
22 | }
23 |
24 | get container() {
25 | return this.value;
26 | }
27 |
28 | init() {
29 | this.value = 'ES6 module';
30 | }
31 |
32 | [privateName](){
33 | console.log("hi");
34 | }
35 | }
36 |
37 |
38 | //usage
39 | let m = new MyModule();
40 | m.container = "hello";
41 | console.log(m.container);
42 | m.privateName();
43 |
--------------------------------------------------------------------------------
/Module/Module.js:
--------------------------------------------------------------------------------
1 | //模块模式
2 |
3 | /*
4 | The Module pattern Module模式
5 | Object literal notation 对象字面量表示法
6 | AMD modules
7 | CommonJS modules
8 | ECMAScript Harmony modules
9 | */
10 | /*********************************************************/
11 | //1.对象字面量表示法
12 | var myModule = {
13 | myProperty: "someValue",
14 | // object literals can contain properties and methods
15 | // e.g we can define a further object for module configuration:
16 | myConfig: {
17 | useCaching: true,
18 | language: "en"
19 | },
20 | // a very basic method
21 | myMethod: function() {
22 | console.log("Where in the world is Paul Irish today?");
23 | },
24 | // output a value based on the current configuration
25 | myMethod2: function() {
26 | console.log("Caching is:" + (this.myConfig.useCaching) ? "enabled" : "disabled");
27 | },
28 | // override the current configuration
29 | myMethod3: function(newConfig) {
30 | if (typeof newConfig === "object") {
31 | this.myConfig = newConfig;
32 | console.log(this.myConfig.language);
33 | }
34 | }
35 | };
36 | // Outputs: Where in the world is Paul Irish today?
37 | myModule.myMethod();
38 | // Outputs: enabled
39 | myModule.myMethod2();
40 | // Outputs: fr
41 | myModule.myMethod3({
42 | language: "fr",
43 | useCaching: false
44 | });
45 | /*********************************************************/
46 | //2.Module(模块)模式
47 | //私有--IIFE模拟
48 | var testModule = (function() {
49 | var counter = 0;
50 | return {
51 |
52 | incrementCounter: function() {
53 | return counter++;
54 | },
55 |
56 | resetCounter: function() {
57 | console.log("counter value prior to reset: " + counter);
58 | counter = 0;
59 | }
60 | };
61 |
62 | })();
63 |
64 | // Usage:
65 |
66 | // Increment our counter
67 | testModule.incrementCounter();
68 |
69 | // Check the counter value and reset
70 | // Outputs: 1
71 | testModule.resetCounter();
72 | /*********************************************************/
73 | //3.Module(模块)模式变化
74 | // 3.1 混入
75 | // Global module
76 | var myModule = (function(jQ, _) {
77 | function privateMethod1() {
78 | jQ(".container").html("test");
79 | }
80 |
81 | function privateMethod2() {
82 | console.log(_.min([10, 5, 100, 2, 1000]));
83 | }
84 |
85 | return {
86 | publicMethod: function() {
87 | privateMethod1();
88 | }
89 | };
90 |
91 | // Pull in jQuery and Underscore
92 | }(jQuery, _));
93 |
94 | myModule.publicMethod();
95 | // 3.2 引出
96 | // Global module对象
97 | var myModule = (function() {
98 | // Module object
99 | var module = {},
100 | privateVariable = "Hello World";
101 |
102 | function privateMethod() {
103 | // ...
104 | }
105 |
106 | module.publicProperty = "Foobar";
107 | module.publicMethod = function() {
108 | console.log(privateVariable);
109 | };
110 |
111 | return module;
112 | }());
113 |
114 | /*********************************************************/
115 |
--------------------------------------------------------------------------------
/Module/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Module/module-in-jquery.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | module in jquery
7 |
8 |
9 |
10 |
11 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Observer/Observer-ES6.js:
--------------------------------------------------------------------------------
1 | /*Subject 目标*/
2 | class Subject {
3 | addObserver() {
4 | throw new Error("This method must be overwritten!");
5 | }
6 | removeObserver() {
7 | throw new Error("This method must be overwritten!");
8 | }
9 | notify() {
10 | throw new Error("This method must be overwritten!");
11 | }
12 | }
13 |
14 | class Observer {
15 | update() {
16 | throw new Error("This method must be overwritten!");
17 | }
18 | }
19 |
20 |
21 | //===============================================================================
22 | //具体的对象
23 | class ControlCheckbox extends Subject {
24 | constructor() {
25 | super();
26 | this.observers = [];
27 | }
28 | addObserver(observer){
29 | this.observers.push(observer);
30 | }
31 | notify(context) {
32 | let observerCount = this.observers.length;
33 | for (let i = 0; i < observerCount; i++) {
34 | this.observers[i].update(context);
35 | }
36 | }
37 | }
38 |
39 |
40 | //具体的观察者
41 | class AddedCheckboxs extends Observer{
42 | constructor(subject){
43 | super();
44 | console.log(subject);
45 | this.subject = subject;
46 | // this.subject.addObserver(this);
47 | }
48 | update(context){
49 | this.checked = context;
50 | }
51 | }
52 |
53 | //main test
54 | let addBtn = document.getElementById("addNewObserver"),
55 | container = document.getElementById("observersContainer"),
56 | controlCheckboxDom = document.getElementById("mainCheckbox");
57 |
58 | let controlCheckbox = new ControlCheckbox();
59 |
60 | controlCheckboxDom.onclick = function(){
61 | controlCheckbox.notify(controlCheckboxDom.checked);//通知了变化
62 | }
63 |
64 | addBtn.onclick = function(){
65 | var check = document.createElement("input");
66 | check.type = "checkbox";
67 | //新增的每一个都应该实现观察者
68 | console.info(controlCheckbox.observers);//查看是否添加上
69 |
70 | check.update = AddedCheckboxs.prototype.update;
71 |
72 | controlCheckbox.addObserver(check);//添加到观察者列表上去
73 |
74 | container.appendChild(check);
75 | }
76 |
--------------------------------------------------------------------------------
/Observer/Observer.js:
--------------------------------------------------------------------------------
1 | //观察者模式
2 | /**
3 | * Subject: maintains a list of observers, facilitates adding or removing observers
4 | * Observer: provides a update interface for objects that need to be notified of a Subject's changes of state
5 | * ConcreteSubject: broadcasts notifications to observers on changes of state, stores the state of ConcreteObservers
6 | * ConcreteObserver: stores a reference to the ConcreteSubject, implements an update interface for the Observer to
7 | * ensure state is consistent with the Subject's
8 | */
9 |
10 | function ObserverList() {
11 | this.observerList = [];
12 | }
13 |
14 | ObserverList.prototype.Add = function(obj) {
15 | return this.observerList.push(obj);
16 | };
17 | ObserverList.prototype.Empty = function() {
18 | this.observerList = [];
19 | };
20 | ObserverList.prototype.Count = function() {
21 | return this.observerList.length;
22 | };
23 | ObserverList.prototype.Get = function(index) {
24 | if (index > -1 && index < this.observerList.length) {
25 | return this.observerList[index];
26 | }
27 | };
28 | ObserverList.prototype.Insert = function(obj, index) {
29 | var pointer = -1;
30 | if (index === 0) {
31 | this.observerList.unshift(obj);
32 | pointer = index;
33 | } else if (index === this.observerList.length) {
34 | this.observerList.push(obj);
35 | pointer = index;
36 | }
37 |
38 | return pointer;
39 | };
40 | ObserverList.prototype.IndexOf = function(obj, startIndex) {
41 | var i = startIndex,
42 | pointer = -1;
43 |
44 | while (i < this.observerList.length) {
45 | if (this.observerList[i] === obj) {
46 | pointer = i;
47 | }
48 | i++;
49 | }
50 |
51 | return pointer;
52 | };
53 | ObserverList.prototype.RemoveAt = function(index) {
54 | if (index === 0) {
55 | this.observerList.shift();
56 | } else if (index === this.observerList.length - 1) {
57 | this.observerList.pop();
58 | }
59 | };
60 | // Extend an object with an extension
61 | function extend(extension, obj) {
62 | for (var key in extension) {
63 | obj[key] = extension[key];
64 | }
65 | }
66 |
67 | /*******************************************************************/
68 | //开始模拟
69 | //Subject 目标
70 | function Subject() {
71 | this.observers = new ObserverList();
72 | }
73 |
74 | Subject.prototype.AddObserver = function(observer) {
75 | this.observers.Add(observer);
76 | };
77 |
78 | Subject.prototype.RemoveObserver = function(observer) {
79 | this.observers.RemoveAt(this.observers.IndexOf(observer, 0));
80 | };
81 | Subject.prototype.Notify = function(context) {
82 | var observerCount = this.observers.Count();
83 | for (var i = 0; i < observerCount; i++) {
84 | this.observers.Get(i).Update(context);
85 | }
86 | };
87 |
88 | //test
89 | function Observer(){
90 | this.Update = function(context){
91 | this.checked = context;
92 | }
93 | }
94 | // References to our DOM elements
95 |
96 | var controlCheckbox = document.getElementById("mainCheckbox"),
97 | addBtn = document.getElementById("addNewObserver"),
98 | container = document.getElementById("observersContainer");
99 |
100 | // Concrete Subject 具体目标,状态改变时候,向Observer发送状态 checked是true或者false
101 |
102 | // Extend the controlling checkbox with the Subject class
103 | extend(new Subject(), controlCheckbox);//目标
104 |
105 | // Clicking the checkbox will trigger notifications to its observers
106 | controlCheckbox["onclick"] = new Function("controlCheckbox.Notify(controlCheckbox.checked)");
107 |
108 |
109 | addBtn["onclick"] = AddNewObserver;
110 |
111 | // Concrete Observer 具体观察者(实现Observer的更新接口,以使自己的状态和目标状态一致)
112 |
113 | function AddNewObserver() {
114 |
115 | // Create a new checkbox to be added
116 | var check = document.createElement("input");
117 | check.type = "checkbox";
118 |
119 | // Extend the checkbox with the Observer class
120 | extend(new Observer(), check);//观察者
121 |
122 | // Override with custom update behaviour
123 | check.Update = function(value) {
124 | this.checked = value;
125 | };
126 |
127 | // Add the new observer to our list of observers
128 | // for our main subject
129 | controlCheckbox.AddObserver(check);
130 |
131 | // Append the item to the container
132 | container.appendChild(check);
133 | }
134 |
--------------------------------------------------------------------------------
/Observer/Publish-Subscribe-ES6.js:
--------------------------------------------------------------------------------
1 | //发布-订阅模式
2 | /*
3 | topics = {},
4 | subUid = -1;
5 | */
6 | class Pubsub {
7 | constructor(){
8 | this.subUid = 0; //订阅的id值
9 | this.topics = {};//存放所有订阅者
10 | }
11 | publish(topic, args) {
12 | if (!this.topics[topic]) {
13 | return false;
14 | }
15 |
16 | let subscribers = this.topics[topic],
17 | len = subscribers ? subscribers.length : 0;
18 |
19 | while (len--) {
20 | subscribers[len].func(topic, args);
21 | }
22 |
23 | return this;
24 | }
25 |
26 | subscribe(topic, func) {
27 | if (!this.topics[topic]) {
28 | this.topics[topic] = [];
29 | }
30 |
31 | let token = (++this.subUid).toString();
32 | this.topics[topic].push({
33 | token: token,
34 | func: func
35 | });
36 | return token;
37 | }
38 | unsubscribe(token) {
39 | for (let m in this.topics) {
40 | if (this.topics[m]) {
41 | for (let i = 0, j = this.topics[m].length; i < j; i++) {
42 | if (this.topics[m][i].token === token) {
43 | this.topics[m].splice(i, 1);
44 | return token;
45 | }
46 | }
47 | }
48 | }
49 | return this;
50 | }
51 | }
52 |
53 |
54 | //usage
55 | let messageLogger = function(topics, data) {
56 | console.log("Logging: " + topics + ": " + data);
57 | };
58 | let pubsub = new Pubsub();
59 |
60 | let subscription = pubsub.subscribe("inbox/newMessage", messageLogger);
61 |
62 | // Publishers are in charge of publishing topics or notifications of
63 | // interest to the application. e.g:
64 |
65 | pubsub.publish("inbox/newMessage", "hello world!");
--------------------------------------------------------------------------------
/Observer/Publish-Subscribe.js:
--------------------------------------------------------------------------------
1 | //订阅-发布模式
2 |
3 | var pubsub = {};
4 | (function(q) {
5 | var topics = {},//存放所有订阅者
6 | subUid = -1;
7 |
8 | // Publish or broadcast events of interest
9 | // with a specific topic name and arguments
10 | // such as the data to pass along
11 | q.publish = function(topic, args) {
12 |
13 | if (!topics[topic]) {
14 | return false;
15 | }
16 |
17 | var subscribers = topics[topic],
18 | len = subscribers ? subscribers.length : 0;
19 |
20 | while (len--) {
21 | subscribers[len].func(topic, args);
22 | }
23 |
24 | return this;
25 | };
26 |
27 | // Subscribe to events of interest
28 | // with a specific topic name and a
29 | // callback function, to be executed
30 | // when the topic/event is observed
31 | q.subscribe = function(topic, func) {
32 | if (!topics[topic]) {
33 | topics[topic] = [];
34 | }
35 |
36 | var token = (++subUid).toString();
37 | topics[topic].push({
38 | token: token,
39 | func: func
40 | });
41 | return token;
42 | };
43 |
44 | // Unsubscribe from a specific
45 | // topic, based on a tokenized reference
46 | // to the subscription
47 | q.unsubscribe = function(token) {
48 | for (var m in topics) {
49 | if (topics[m]) {
50 | for (var i = 0, j = topics[m].length; i < j; i++) {
51 | if (topics[m][i].token === token) {
52 | topics[m].splice(i, 1);
53 | return token;
54 | }
55 | }
56 | }
57 | }
58 | return this;
59 | };
60 | }(pubsub));
61 |
62 | // A simple message logger that logs any topics and data received through our
63 | // subscriber
64 | var messageLogger = function(topics, data) {
65 | console.log("Logging: " + topics + ": " + data);
66 | };
67 |
68 | // Subscribers listen for topics they have subscribed to and
69 | // invoke a callback function (e.g messageLogger) once a new
70 | // notification is broadcast on that topic
71 | var subscription = pubsub.subscribe("inbox/newMessage", messageLogger);
72 |
73 | // Publishers are in charge of publishing topics or notifications of
74 | // interest to the application. e.g:
75 |
76 | pubsub.publish("inbox/newMessage", "hello world!");
77 |
78 | // or
79 | pubsub.publish("inbox/newMessage", ["test", "a", "b", "c"]);
80 |
81 | // or
82 | pubsub.publish("inbox/newMessage", {
83 | sender: "hello@google.com",
84 | body: "Hey again!"
85 | });
86 |
87 | // We cab also unsubscribe if we no longer wish for our subscribers
88 | // to be notified
89 | // pubsub.unsubscribe( subscription );
90 |
91 | // Once unsubscribed, this for example won't result in our
92 | // messageLogger being executed as the subscriber is
93 | // no longer listening
94 | pubsub.publish("inbox/newMessage", "Hello! are you still there?");
95 |
--------------------------------------------------------------------------------
/Observer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 设计模式
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Observer/publish-subcribe.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 设计模式
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # javascript-design-pattern
2 | javascript设计模式【ES5和ES6语法】
3 |
4 | 博客地址:
5 | - [javascript设计模式【上】http://blog.csdn.net/future_todo/article/details/53992141](http://blog.csdn.net/future_todo/article/details/53992141)
6 | - [javascript设计模式【下】http://blog.csdn.net/future_todo/article/details/53992145](http://blog.csdn.net/future_todo/article/details/53992145)
7 | - [javascript设计模式 使用ES6语法 http://blog.csdn.net/future_todo/article/details/53992152](http://blog.csdn.net/future_todo/article/details/53992152)
8 |
9 |
--------------------------------------------------------------------------------
/Revealing/Revealing.js:
--------------------------------------------------------------------------------
1 | // Revealing Module 揭示模块模式
2 |
3 | var myRevealingModule = function() {
4 | var privateVar = "Ben Cherry",
5 | publicVar = "Hey there!";
6 |
7 | function privateFunction() {
8 | console.log("Name:" + privateVar);
9 | }
10 |
11 | function publicSetName(strName) {
12 | privateVar = strName;
13 | }
14 |
15 | function publicGetName() {
16 | privateFunction();
17 | }
18 |
19 | // Reveal public pointers to
20 | // private functions and properties
21 |
22 | return {
23 | setName: publicSetName,
24 | greeting: publicVar,
25 | getName: publicGetName
26 | };
27 |
28 | }();
29 |
30 | myRevealingModule.setName("Paul Kinlan");
31 |
--------------------------------------------------------------------------------
/Revealing/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Singleton/SingLeton.js:
--------------------------------------------------------------------------------
1 | // 单例模式
2 | var mySingleton = (function() {
3 | // Instance stores a reference to the Singleton
4 | var instance;
5 |
6 | function init() {
7 |
8 | // Singleton
9 |
10 | // Private methods and variables
11 | function privateMethod() {
12 | console.log("I am private");
13 | }
14 |
15 | var privateVariable = "Im also private";
16 |
17 | var privateRandomNumber = Math.random();
18 |
19 | return {
20 |
21 | // Public methods and variables
22 | publicMethod: function() {
23 | console.log("The public can see me!");
24 | },
25 |
26 | publicProperty: "I am also public",
27 |
28 | getRandomNumber: function() {
29 | return privateRandomNumber;
30 | }
31 |
32 | };
33 |
34 | };
35 |
36 | return {
37 |
38 | // Get the Singleton instance if one exists
39 | // or create one if it doesn't
40 | getInstance: function() {
41 |
42 | if (!instance) {
43 | instance = init();
44 | }
45 |
46 | return instance;
47 | }
48 |
49 | };
50 |
51 | })();
52 |
53 |
54 | //==============================================================
55 | //Singleton 和静态实例
56 | var SingletonTester = (function() {
57 |
58 | // options: an object containing configuration options for the singleton
59 | // e.g var options = { name: "test", pointX: 5};
60 | function Singleton(options) {
61 |
62 | // set options to the options supplied
63 | // or an empty object if none are provided
64 | options = options || {};
65 |
66 | // set some properties for our singleton
67 | this.name = "SingletonTester";
68 |
69 | this.pointX = options.pointX || 6;
70 |
71 | this.pointY = options.pointY || 10;
72 |
73 | }
74 |
75 | // our instance holder
76 | var instance;
77 |
78 | // an emulation of static variables and methods
79 | var _static = {
80 | name: "SingletonTester",
81 | // Method for getting an instance. It returns
82 | // a singleton instance of a singleton object
83 | getInstance: function(options) {
84 | if (instance === undefined) {
85 | instance = new Singleton(options);
86 | }
87 |
88 | return instance;
89 | }
90 | };
91 |
92 | return _static;
93 |
94 | })();
95 |
96 | var singletonTest = SingletonTester.getInstance({
97 | pointX: 5
98 | });
99 |
100 | // Log the output of pointX just to verify it is correct
101 | // Outputs: 5
102 | console.log(singletonTest.pointX);
103 |
--------------------------------------------------------------------------------
/Singleton/Singleton-ES6.js:
--------------------------------------------------------------------------------
1 | let instance = null;
2 | class mySingleton {
3 | constructor() {
4 | if (!instance) instance = this;
5 | return instance;
6 | }
7 |
8 | publicMethod() {
9 | console.log("The public can see me!");
10 | }
11 | //静态方法
12 | static getRandomNumber() {
13 | return 'hello';
14 | }
15 | }
16 |
17 | //静态属性
18 | let mySingleton.publicProperty = "I am also public"
19 |
20 | let singleton1 = new mySingleton();
21 | let singleton2 = new mySingleton();
22 |
23 | //========================================================================
24 | class mySingleton {
25 | static getInstance() {
26 | if (!mySingleton.instance) {
27 | mySingleton.instance = new mySingleton();
28 | }
29 | return mySingleton.instance;
30 | }
31 | publicMethod() {
32 | console.log("The public can see me!");
33 | }
34 | }
35 |
36 | var cache = mySingleton.getInstance();
37 |
--------------------------------------------------------------------------------
/Singleton/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 设计模式
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/jqueryPlugin/Lightweight-Start.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery lightweight plugin boilerplate
3 | * Original author: @ajpiano
4 | * Further changes, comments: @addyosmani
5 | * Licensed under the MIT license
6 | */
7 |
8 | // the semi‐colon before the function invocation is a safety
9 | // net against concatenated scripts and/or other plugins
10 | // that are not closed properly.
11 | // 分号为了安全,防止其他的插件没有正常关闭
12 | ; (function($, window, document, undefined) {
13 |
14 | // undefined is used here as the undefined global
15 | // variable in ECMAScript 3 and is mutable (i.e. it can
16 | // be changed by someone else). undefined isn't really
17 | // being passed in so we can ensure that its value is
18 | // truly undefined. In ES5, undefined can no longer be
19 | // modified.
20 |
21 | // window and document are passed through as local
22 | // variables rather than as globals, because this (slightly)
23 | // quickens the resolution process and can be more
24 | // efficiently minified (especially when both are
25 | // regularly referenced in our plugin).
26 |
27 | // Create the defaults once 创建默认值
28 | var pluginName = "defaultPluginName",
29 | defaults = {
30 | propertyName: "value"
31 | };
32 |
33 | // The actual plugin constructor
34 | function Plugin(element, options) {
35 | this.element = element;
36 |
37 | // jQuery has an extend method that merges the
38 | // contents of two or more objects, storing the
39 | // result in the first object. The first object
40 | // is generally empty because we don't want to alter
41 | // the default options for future instances of the plugin
42 | this.options = $.extend({}, defaults, options);
43 |
44 | this._defaults = defaults;
45 | this._name = pluginName;
46 |
47 | this.init();
48 | }
49 |
50 | Plugin.prototype.init = function() {
51 | // Place initialization logic here
52 | // We already have access to the DOM element and
53 | // the options via the instance, e.g. this.element
54 | // and this.options
55 | console.log(this.options);
56 | };
57 |
58 | // A really lightweight plugin wrapper around the constructor,
59 | // preventing against multiple instantiations
60 | $.fn[pluginName] = function(options) {
61 | return this.each(function() {
62 | if (!$.data(this, "plugin_" + pluginName)) {
63 | $.data(this, "plugin_" + pluginName,
64 | new Plugin(this, options));
65 | }
66 | });
67 | }
68 |
69 | })(jQuery, window, document);
70 |
71 |
72 | //usage
73 | $("#elem").defaultPluginName({
74 | propertyName: "a custom value"
75 | });
76 |
--------------------------------------------------------------------------------
/jqueryPlugin/WidgetFactory.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery UI Widget‐factory plugin boilerplate (for 1.8/9+)
3 | * Author: @addyosmani
4 | * Further changes: @peolanha
5 | * Licensed under the MIT license
6 | */
7 |
8 | ; (function($, window, document, undefined) {
9 |
10 | // define our widget under a namespace of your choice
11 | // with additional parameters e.g.
12 | // $.widget( "namespace.widgetname", (optional) ‐ an
13 | // existing widget prototype to inherit from, an object
14 | // literal to become the widget's prototype );
15 | //在指定命名空间下创建widget
16 | $.widget("namespace.widgetName", {
17 | //Options to be used as defaults
18 | options: {
19 | someValue: null
20 | },
21 |
22 | //Setup widget (e.g. element creation, apply theming
23 | // , bind events etc.)
24 | _create: function() {
25 |
26 | // _create will automatically run the first time
27 | // this widget is called. Put the initial widget
28 | // setup code here, then we can access the element
29 | // on which the widget was called via this.element.
30 | // The options defined above can be accessed
31 | // via this.options this.element.addStuff();
32 | console.log(this);
33 | },
34 |
35 | // Destroy an instantiated plugin and clean up
36 | // modifications the widget has made to the DOM
37 | destroy: function() {
38 |
39 | // this.element.removeStuff();
40 | // For UI 1.8, destroy must be invoked from the
41 | // base widget
42 | $.Widget.prototype.destroy.call(this);
43 | // For UI 1.9, define _destroy instead and don't
44 | // worry about
45 | // calling the base widget
46 | },
47 |
48 | methodB: function(event) {
49 | //_trigger dispatches callbacks the plugin user
50 | // can subscribe to
51 | // signature: _trigger( "callbackName" , [eventObject],
52 | // [uiObject] )
53 | // e.g. this._trigger( "hover", e /*where e.type ==
54 | // "mouseenter"*/, { hovered: $(e.target)});
55 | this._trigger("methodA", event, {
56 | key: value
57 | });
58 | },
59 |
60 | methodA: function(event) {
61 | this._trigger("dataChanged", event, {
62 | key: value
63 | });
64 | },
65 |
66 | // Respond to any changes the user makes to the
67 | // option method
68 | _setOption: function(key, value) {
69 | switch (key) {
70 | case "someValue":
71 | this.options.someValue = doSomethingWith( value );
72 | break;
73 | default:
74 | this.options[ key ] = value;
75 | break;
76 | }
77 |
78 | // For UI 1.8, _setOption must be manually invoked
79 | // from the base widget
80 | $.Widget.prototype._setOption.apply(this, arguments);
81 | // For UI 1.9 the _super method can be used instead
82 | // this._super( "_setOption", key, value );
83 | }
84 | });
85 |
86 | })(jQuery, window, document);
87 |
88 |
89 | var collection = $("#elem").widgetName({
90 | foo: false
91 | });
92 |
93 | collection.widgetName("methodB");
94 |
--------------------------------------------------------------------------------
/jqueryPlugin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | jquery插件
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------