单例模式
系统中被唯一使用,一个类只有一个实例
class Store {
action() {
console.log('vue store')
}
}
Store.getInstance = (function() {
let instance;
return function() {
if (!instance) {
instance = new Store();
}
return instance;
}
})()
//此代码存在闭包,因此instance的值会被保存
//第一次进来创建一个新的对象,但是之后创建对象都直接返回之前创建的那个对象,因此只有一个实例
优点:
- 在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就防止其它对象对自己的实例化,确保所有的对象都访问一个实例
- 避免对共享资源的多重占用。
工厂模式
最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式
var MobileFactory = (function() {
var Mobile = function(name,model) {
this.model = model;
this.name = name;
}
//在函数原型对象上添加方法
Mobile.prototype.play = function() {
console.log(...)
}
return function(name,model) {
return new Mobile(name,model);
}
})()
var p1 = new MobileFactory('iphone','6');
p1.play();
/**************************************/
//es6
class Product {
constructor(name,model) {
this.name = name;
this.model = model;
}
play() {
console.log("Mobile:"+this.name+""+this.model)
}
}
class FactoryCreator {
create(name,model) {
return new Product(name,model)
}
}
let creator = new FactoryCreator();
let p = creator.create('iphone','6');
优点:
- 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接
创建产品对象的责任,而仅仅**"消费"产品**。工厂模式通过这种做法实现了对责任的分割。 - 当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类
集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
缺点:
3. 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂, 违背了"开 放–封闭"原则(OCP)
代理模式
代理是一个对象,跟本体对象具有相同的接口,以此达到对本体对象的访问控制
var girl = function(name) {
this.name = name;
}
var boy = function(girl) {
this.girl = girl;
this.sendGift = function(gift) {
alert("Hi " + girl.name + ", 男孩送你一个礼物:" + gift);
}
}
var proxyObj = function(girl) {
this.girl = girl;
this.sendGift = function(gift) {
(new boy(girl)).sendGift(gift);
}
}
var proxy = new proxyObj(new girl("花花"))
proxy.sendGift('999朵玫瑰')
**优点:**代理对象可以代替本体对象被实例化,此时本体对象未真正实例化,等到合适时机再实例化。
代理模式可以延迟创建开销很大的本体对象,他会把本体的实例化推迟到有方法被调用时。(高内聚,低耦合)
观察者模式
当一个对象数据发生变化时,通知其它一系列对象,让其响应这种变化
观察者设计模式中主要区分两个概念:
观察者:指观察者对象,也就是消息的订阅者;
被观察者:指要观察的目标对象,也就是消息的发布者。
class Subject{ //发布者
constructor() {
this.subs = [];
}
addSub(sub) {//添加订阅者
this.subs.push(sub);
}
notify(food) {//通知
this.subs.forEach(sub => {
sub.update(food);
})
}
}
class Observer {//订阅者
constructor(name,food) {
this.name = name;
this.food = food;
}
update(food) {
if (food = this.food) {
console.log(this.name + "的外卖:"+food);
}
}
}
var subject = new Subject();
var tom = new Observer('tom','第三鲜');
var jack = new Observer('jack','红烧肉');
//添加观察者
subject.addSub(tom);
subject.addSub(jack);
//目标发布消息调用观察者的更新方法了
subject.notify("地三鲜");
subject.notify("红烧肉");
适配器模式
将原本不适合的数据转换为适合的数据(计算属性)。
将原本不适合的接口转换为适合的接口。
优点:
- 将目标类和适配者类解耦.
- 增加了类的透明性和复用性,将具体的实现封装在适配者类中.
装饰器模式
允许向一个现有的对象添加新的功能,同时又不改变其结构。
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式可以动态扩展一个实现类的功能。
class Circle {
draw() {
console.log('画圆')
}
}
class Decotator {
constructor(circle) {
this.circle = circle;
}
draw() {
this.circle.draw();
this.setBorder(circle);
}
setBorder(circle) {
console.log('加上边框')
}
}
let circle = new Circle();
circle.draw();
//不断叠加
let dec = new Decorator(circle);
dec.draw();