什么是设计模式
假设有一个空房间,我们要日复一日地往里 面放一些东西。最简单的办法当然是把这些东西 直接扔进去,但是时间久了,就会发现很难从这 个房子里找到自己想要的东西,要调整某几样东 西的位置也不容易。所以在房间里做一些柜子也 许是个更好的选择,虽然柜子会增加我们的成 本,但它可以在维护阶段为我们带来好处。使用 这些柜子存放东西的规则,就是一种模式。
学习设计模式,有助于写出可复用和可维护性高的程序。
单例模式
什么是单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点
核心
确保只有一个实例,并提供全局访问
优缺点
- 内存中只有一个实例,减少了内存的开销。
- 避免了对资源多重的占用。
- 违反了单一职责,一个类应该只关心内部逻辑,而不用去关心外部的实现。
实现
function creatSingleton() {
var j = null
// 实例如已经创建过,直接返回
if (!j) {
j = 22
}
return j
}
装饰模式
什么是装饰模式
装饰者模式能够在不更改源代码自身的情况下,对其进行职责添加。相比于继承装饰器的做法更轻巧。通俗的讲我们给心爱的手机上贴膜,带上手机壳,贴纸,这些就是对手机的装饰。
优缺点
- 装饰类和被装饰类它们之间可以相互独立发展,不会相互耦合,装饰器模式是继承的一个替代模式,它可以动态的扩展一个实现类的功能。
- 多层的装饰会增加复杂度。
实例
在编写飞机大战的游戏中,飞机对象的攻击方式只有普通子弹攻击,如何在不更改原代码的情况下,为它其他的攻击方式,如激光武器,导弹武器?
代码实现:
class Aircraft {
ordinary(){
console.log('发射普通子弹')
}
}
class AircraftDecorator {
constructor(aircraft){
this.aircraft = aircraft
}
laser(){
console.log('发射激光')
}
guidedMissile(){
console.log('发射导弹')
}
ordinary(){
this.aircraft.ordinary()
}
}
const aircraft = new Aircraft()
const aircraftDecorator = new AircraftDecorator(aircraft)
aircraftDecorator.ordinary() // 发射普通子弹
aircraftDecorator.laser() // 发射激光
aircraftDecorator.guidedMissile() // 发射导弹
观察者模式
什么是观察者模式
观察者模式,它定义对象之间的1对N的依赖关系,当其中一个对象发生变化时,所有依赖于它的对象都会得到通知。
优缺点
- 观察者和被观察者它们之间是抽象耦合的。并且建立了触发机制。
- 当订阅者比较多的时候,同时通知所有的订阅者可能会造成性能问题。
- 在订阅者和订阅目标之间如果循环引用执行,会导致崩溃。
- 发布订阅模式没有办法提供给订阅者所订阅的目标它是怎么变化的,仅仅只知道它变化了。
实例
比如前段时间的冬奥会,项目还没有开始的时候可以提前预定,等到项目快开始的时,APP会提前给我们发送通知即将开始的项目,而没到时间的不通知,另外在项目还没有开始的时候,可以取消订阅避免接受到通知。
代码实现:
function Observer(){
}
Observer.prototype.update=function(){
console.log('工作')
}
function ObserverList(){
this.list = [];
}
ObserverList.prototype.add=function(obj){
this.list.push(obj)
}
ObserverList.prototype.empty=function(){
this.list=[];
}
ObserverList.prototype.remove=function(obj){
for(let i=0;i<this.list.size;i++){
if(list[i]==obj){
this.list.splice(0,1,obj);
return;
}
}
}
function Subject(){
this.objserverList=new ObserverList();
this.state=null;
}
Subject.prototype.addObser=function(observe){
this.objserverList.add(observe)
}
Subject.prototype.removeObser=function(observe){
this.objserverList.remove(observe)
}
Subject.prototype.notify=function(){
let list = this.objserverList.list
list.forEach(e=>{
e.update();
})
}
Subject.prototype.setState=function(newState){
this.state= newState;
this.notify();
}
Subject.prototype.getState=function(){
return this.state;
}