第六十课:JavaScript设计模式
学习目标
在本节课程中,我们的目标是了解和掌握以下几种常见的JavaScript设计模式:
- 单例模式(Singleton Pattern)
- 观察者模式(Observer Pattern)
- 模块模式(Module Pattern)
- 工厂模式(Factory Pattern)
学习内容
1. 单例模式(Singleton Pattern)
-
概念:确保一个类只有一个实例,并提供一个全局访问点。
-
代码示例:
var Singleton = (function () { var instance; function createInstance() { var object = new Object("I am the instance"); return object; } return { getInstance: function () { if (!instance) { instance = createInstance(); } return instance; } }; })(); var instance1 = Singleton.getInstance(); var instance2 = Singleton.getInstance(); console.log(instance1 === instance2); // true
-
预计输出:
true
,因为instance1
和instance2
都指向同一个实例。
2. 观察者模式(Observer Pattern)
-
概念:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。
-
代码示例:
function Subject() { this.observers = []; // 观察者列表 } Subject.prototype = { subscribe: function (fn) { this.observers.push(fn); }, unsubscribe: function (fnToRemove) { this.observers = this.observers.filter(fn => { if (fn !== fnToRemove) return fn; }); }, fire: function () { this.observers.forEach(fn => { fn.call(); }); } }; const subject = new Subject(); function observer1() { console.log("Observer 1 Firing!"); } function observer2() { console.log("Observer 2 Firing!"); } subject.subscribe(observer1); subject.subscribe(observer2); subject.fire();
-
预计输出:
Observer 1 Firing! Observer 2 Firing!
3. 模块模式(Module Pattern)
-
概念:创建私有变量和函数,同时暴露出一个公开的接口。
-
代码示例:
var ShoppingCart = (function () { var basket = []; return { addItem: function (item) { basket.push(item); }, getItemCount: function () { return basket.length; }, getTotal: function () { return basket.reduce((total, item) => { return total + item.price; }, 0); } }; })(); ShoppingCart.addItem({ item: "bread", price: 0.5 }); ShoppingCart.addItem({ item: "butter", price: 0.3 }); console.log(ShoppingCart.getItemCount()); // 2 console.log(ShoppingCart.getTotal()); // 0.8
-
预计输出:
2 0.8
4. 工厂模式(Factory Pattern)
-
概念:使用一个创建对象的接口,但由子类决定实例化的类是哪一个。工厂方法让类的实例化推迟到子类中进行。
-
代码示例:
function Car(options) { this.doors = options.doors || 4; this.state = options.state || "brand new"; this.color = options.color || "silver"; } function Truck(options) { this.state = options.state || "used"; this.wheelSize = options.wheelSize || "large"; this.color = options.color || "blue"; } function VehicleFactory() 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); }; var carFactory = new VehicleFactory(); var car = carFactory.createVehicle({ vehicleType: "car", color: "yellow", doors: 2 }); console.log(car instanceof Car); // true console.log(car); // Car { doors: 2, state: 'brand new', color: 'yellow' }
-
预计输出:
true Car { doors: 2, state: 'brand new', color: 'yellow' }
课后练习
练习1:单例模式
创建一个名为DatabaseManager
的单例,它应该包含connect
方法,该方法打印出连接到数据库的消息。确保无论你尝试创建多少次DatabaseManager
的实例,它都只会给你一个实例。
练习2:观察者模式
实现一个简单的事件管理器,允许你订阅事件、取消订阅事件以及触发事件。
练习3:模块模式
创建一个模块User
,它有私有变量userCount
,以及公开的方法addUser
和getUserCount
。addUser
方法增加userCount
的值,getUserCount
返回当前的userCount
。
练习4:工厂模式
使用工厂模式创建两种类型的交通工具:自行车和汽车。每种交通工具都应该接受不同的参数,比如自行车的wheelType
和汽车的fuelType
。
解析
练习1解析:
var DatabaseManager = (function () {
var instance;
function createInstance() {
var object = new Object("I am the instance");
return object;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
var db1 = DatabaseManager.getInstance();
var db2 = DatabaseManager.getInstance();
console.log(db1 === db2); // true
练习2解析:
function EventManager() {
this.events = {};
}
EventManager.prototype = {
subscribe: function (event, fn) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(fn);
},
unsubscribe: function (event, fnToRemove) {
if (this.events[event]) {
this.events[event] = this.events[event].filter(fn => fn !== fnToRemove);
}
},
trigger: function (event) {
if (this.events[event]) {
this.events[event].forEach(fn => {
fn.call();
});
}
}
};
练习3解析:
var User = (function () {
var userCount = 0;
return {
addUser: function () {
userCount++;
},
getUserCount: function () {
return userCount;
}
};
})();
User.addUser();
User.addUser();
console.log(User.getUserCount()); // 2
练习4解析:
function VehicleFactory()VehicleFactory.prototype.createVehicle = function (options) {
switch (options.vehicleType) {
case "car":
return new Car(options);
case "bike":
return new Bike(options);
default:
return null;
}
};
function Car(options) {
this.fuelType = options.fuelType || "gasoline";
}
function Bike(options) {
this.wheelType = options.wheelType || "standard";
}
var factory = new VehicleFactory();
var car = factory.createVehicle({
vehicleType: "car",
fuelType: "diesel"
});
var bike = factory.createVehicle({
vehicleType: "bike",
wheelType: "mountain"
});
console.log(car instanceof Car); // true
console.log(bike instanceof Bike); // true
通过完成这些练习,你将能够加深对不同设计模式的理解,并学会如何在JavaScript中实现它们。