结构化模型如何将对象和类组装成大结构,同时保持结构的灵活性和效率?
从这一节开始,我们开始学习结构型设计模式。 首先,学习第一种“享受源模式”和比较简单的结构型设计模式吧
享元模式的定义
享元模式是什么? 还是能“忘记文生义”? 享受是共享,原本是要素共享的要素的意思。 那么,如何共享要素呢? 很容易想到。 是共享池。 了解java的同学应该知道java中有线程池。 是的。以下是使用共享对象池缓存对象的正式定义。 使用空对象(如果有),否则在池中创建新对象,然后返回使用。
享元模式的作用
运气模式的主要作用是可以共享对象以避免创建过多的对象,从而减少内存使用量。 由于具有此特征,因此它适合应用于创建大量重复对象的场景,以缓存可共享对象。这样可以减少对象的创建,提高内存和性能
以下几个场景需要元模式
系统中存在许多类似对象,需要缓冲池的场景消息队列也使用了源模式。 举个简单的例子来说明享受源模式的使用方法
首先需要抽象的类,即享有方对象。 例如,dom事件具有各种事件共有的父类,如单击事件、长按事件、右键单击事件和键盘事件。 我们命名为“事件”。 这是一个称为抽象类的抽象类,它是无法实例化对象的类,只能用作其他类的父类
js没有抽象类这个概念。 java是abstract,其中包含可以定义抽象类的关键字
那么,js如何定义抽象类,而无需实例化对象呢? 不管有没有关键词。 我们能达到目的就好了。 如果你知道原理,有几种方法可以实现
使用new.target,可以实现类似Java的抽象类
如果没有在new命令中调用构造函数,new.target将返回undefined,因此可以使用此属性来确定如何调用构造函数。 如果子类继承父类,new.target将返回子类。
事件的源代码如下:
//抽象类,无法实例化
类事件{
构造器
if(new.target===event ) {
throw new (“此类无法实例化”
}
}
doSomething () }
console.log (('在此做某事) ) ) ) )。
}
}从上面的源代码可以看出,在构造函数中使用new.target来定义抽象类,以防止直接通过new对象
基类完成后,需要定义具体的类。 例如,将单击事件ClickEvent源代码定义如下:
//具体类
类clickevent extends event {
构造器
super () ) )
}
doSomething () }
console.log (这是点击事件) ) )
}
}
代码很简单。 没什么好说的。 这里有需要注意的事情。 这意味着必须在构造函数中调用父类的构造函数
现在,让我们来定义如何对外暴露获取事件的途径,称为象池,或事件工厂
还需要一个变量来保存要共享的对象。 最适合Map结构
源代码如下:
//定义共享池
类事件工厂{
构造器
//决定事件池,即上面定义中所说的对象池
//js中为弱类型,java中必须指定类型,如this.Events=new HashMapString,event
//正因为如此,才需要定义事件类。 在js中,可以完全省略Event类的定义,但最好知道其原因
//TS有明确的类型
this.events=new Map (
}
//从目标池获取对象
获取事件(key ) {
//如果在游泳池里就返回
if(this.Events.get ) (key ) ) )。
return this.events.get(key )
}
//如果不在池中,则创建一个并放入池中,然后返回
let event=new ClickEvent (
this.Events.set (密钥,event ) )。
返回事件
}
}如上面的代码注释所示,如果有,则返回原样;如果不在池中,则创建新的共享源对象,放入池中,然后返回新创建的对象。
这就是享元模式的思想,虽然简单,但很有用
发布了完整的源代码,包括测试代码。 如下所示。
' use strict ';
//抽象类,无法实例化
类事件{
构造器
if(new.target===event ) {
throw new (“此类无法实例化”
}
}
doSomething () }
console.log (('在此做某事) ) ) ) )。
}
}
//具体类
类clickevent extends event {
构造器
super () ) )
}
doSomething () }
console.log (这是点击事件) ) )
}
}
//定义共享池
类事件工厂{
构造器
//决定事件池,即上面定义中所说的对象池
//js中为弱类型,java中必须指定类型,如this.Events=new HashMapString,event
//正因为如此,才需要定义事件类。 在js中,可以完全省略Event类的定义,但最好知道其原因
//TS有明确的类型
this.events=new Map (
}
//从目标池获取对象
获取事件(key ) {
//如果在游泳池里就返回
if(this.Events.get ) (key ) ) )。
return this.events.get(key )
}
//如果不在池中,则创建一个并放入池中,然后返回
let event=new ClickEvent (
this.Events.set (密钥,event ) )。
返回事件
}
}
执行结果如下
这是一个点击活动