一、单例模式
从定义来看,一个类只有一个实例。即一个构造函数只能有一个实例,无论new多少次,都是这一个实例。
单例模式保证一个类仅有一个实例,并提供全局访问。
function VirtualDom(name, age) {
this.name = name,
this.age = age
}
VirtualDom.getInstance = (function(){
let instance;
return function(name, age) {
if (!(instance instanceof VirtualDom)){
instance = new VirtualDom(name, age);
}
return instance;
}
})();
let obj1 = VirtualDom.getInstance('admin', 12);
let obj2 = VirtualDom.getInstance('root', 18);
console.log(obj1 == obj2); //true
console.log(obj1);
console.log(obj2);
二、 静态工厂模式
由一个工厂对象来决定创建某一种产品对象类的实例,主要用来创建同一类对象。
调用需要的功能到工厂里获取,无需关注创建过程。
class API {
procure() {
throw new Error('该方法不能直接调用');
}
make() {
throw new Error('该方法不能直接调用');
}
package() {
throw new Error('该方法不能直接调用');
}
sell() {
throw new Error('该方法不能直接调用');
}
}
class Phone extends API {
typeName = '手机';
procure() {
console.log(`${this.typeName} 正在采购原材料`);
}
make() {
console.log(`${this.typeName} 正在制作`);
}
package() {
console.log(`${this.typeName} 正在打包`);
}
sell() {
console.log(`${this.typeName} 正在售卖`);
}
}
class Computer extends API {
typeName = '电脑';
procure() {
console.log(`${this.typeName} 正在采购原材料`);
}
make() {
console.log(`${this.typeName} 正在制作`);
}
package() {
console.log(`${this.typeName} 正在打包`);
}
sell() {
console.log(`${this.typeName} 正在售卖`);
}
}
// 方式一
// class Factory {
// static create(what){
// let obj = null;
// eval(` obj = new ${what}();`);
// return obj;
// }
// }
// let what = Factory.create('Phone');
// what.sell();
// 方式二
class Factory {
static create(what, dowhat){
let obj = null;
eval(` obj = new ${what}();`);
obj[dowhat]();
}
}
Factory.create('Computer', 'sell');
三、观察者模式
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。
// 主体对象Subject(1个)
class Subject {
constructor() {
this.state = 0;
this.observer = [];
}
getState() {
return this.state;
}
setState(state) {
this.state = state;
this.notifuAllObserver();
}
attach(observer) {
this.observer.push(observer);
this.notifuAllObserver();
}
// 广播
notifuAllObserver() {
this.observer.forEach(once => {
once.update();
})
}
}
// 观察者Observer
class Observer {
constructor(name, subject) {
this.name = name;
this.subject = subject;
this.subject.attach(this);
}
update() {
console.log(`this name is ${this.name}, to do update, state value = ${this.subject.state}()`);;
}
}
// 主体对象
let sub = new Subject();
// 观察者
let obj1 = new Observer('张三', sub);
let obj2 = new Observer('李四', sub);
四、适配器模式
适配器用来解决两个已有接口之间不匹配的问题,它并不需要考虑接口是如何实现,也不用考虑将来该如何修改;适配器不需要修改已有接口,就可以使他们协同工作。
class Api {
alert(){
throw new Error('该方法不可直接被调用');
}
}
class Phone extends Api{
alert(){
console.log('手机的alert()方法');
}
}
class Computer extends Api{
alert(){
console.log('电脑的alert()方法');
}
}
class Target extends Api{
#targetObj;
constructor(className){
super();
eval(`this.targetObj = new ${className}();`);
}
alert(){
this.targetObj.alert();
}
}
let obj = new Target('Phone');
obj.targetObj = new Phone();
obj.alert();
五、注册者模式
function Simple() {
}
function Simple2() {
}
Simple.getInstance = (function(){
let instance = []; //数组键值对arr['Simple'] = new Simple();
return function(simple) {
if(! instance[simple]){
eval(`instance[simple] = new ${Simple}();`);
}
return instance[simple];
}
})();
let obj1 = Simple.getInstance('Simple');
let obj2 = Simple.getInstance('Simple2');
console.log(obj1 == obj2); //false