使用场景
为了解决多个类似对象声明的问题,我们可以使用一种叫做 工厂模式的方法,这种方法 就是为了解决实例化对象产生大量重复的问题。
大致区分类型
简单工厂
- 简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
-
工厂方法模式
工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。
-
抽象工厂
抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。
- 应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。
简单工厂模式
简单工厂模式其实并不算是一种设计模式,更多的时候是一种编程习惯。
定义
定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。
demo
User就是一个简单工厂,在该函数中有3个实例中分别对应不同的权限的用户。当我们调用工厂函数时,只需要传递superAdmin, admin, user这三个可选参数中的一个获取对应的实例对象。
//User类class User {//构造器constructor(opt) {this.name = opt.name;this.viewPage = opt.viewPage;}//静态方法static getInstance(role) {switch (role) {case 'superAdmin':return new User({ name: '超级管理员', viewPage: ['首页', '通讯录', '发现页', '应用数据', '权限管理'] });break;case 'admin':return new User({ name: '管理员', viewPage: ['首页', '通讯录', '发现页', '应用数据'] });break;case 'user':return new User({ name: '普通用户', viewPage: ['首页', '通讯录', '发现页'] });break;default:throw new Error('参数错误, 可选参数:superAdmin、admin、user')}}}//调用let superAdmin = User.getInstance('superAdmin');let admin = User.getInstance('admin');let normalUser = User.getInstance('user');
工厂方法模式
工厂方法模式是简单工厂的仅一步深化, 在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂。
demo
class User {constructor(name = '', viewPage = []) {if(new.target === User) {throw new Error('抽象类不能实例化!');}this.name = name;this.viewPage = viewPage;}}class UserFactory extends User {constructor(name, viewPage) {super(name, viewPage)}create(role) {switch (role) {case 'superAdmin':return new UserFactory( '超级管理员', ['首页', '通讯录', '发现页', '应用数据', '权限管理'] );break;case 'admin':return new UserFactory( '普通用户', ['首页', '通讯录', '发现页'] );break;case 'user':return new UserFactory( '普通用户', ['首页', '通讯录', '发现页'] );break;default:throw new Error('参数错误, 可选参数:superAdmin、admin、user')}}}
抽象工厂模式
**抽象工厂模式并不直接生成实例, 而是用于对产品类簇的创建**
demo
/*** 实现 subType类对工厂类中的superType类型的抽象类的继承* @param subType 要继承的类* @param superType 工厂类中的抽象类type*/const VehicleFactory = function(subType, superType) {if (typeof VehicleFactory[superType] === 'function') {function F() {this.type = '车辆'}F.prototype = new VehicleFactory[superType]()subType.constructor = subTypesubType.prototype = new F()// 因为子类subType不仅需要继承superType对应的类的原型方法,还要继承其对象属性} else throw new Error('不存在该抽象类')}VehicleFactory.Car = function() {this.type = 'car'}VehicleFactory.Car.prototype = {getPrice: function() {return new Error('抽象方法不可使用')},getSpeed: function() {return new Error('抽象方法不可使用')}}const BMW = function(price, speed) {this.price = pricethis.speed = speed}VehicleFactory(BMW, 'Car') // 继承Car抽象类BMW.prototype.getPrice = function() { // 覆写getPrice方法console.log(`BWM price is ${this.price}`)}BMW.prototype.getSpeed = function() {console.log(`BWM speed is ${this.speed}`)}const baomai5 = new BMW(30, 99)baomai5.getPrice() // BWM price is 30baomai5 instanceof VehicleFactory.Car // true
