js中的工厂模式,单例模式,中介者模式
1.工厂模式
- 传入数据,函数内进行加工后,生成一个局部变量,最后return这个局部变量
- 因为返回的是局部变量,所以即使传进的是一样的数据,生成的东西也不一样(引用地址不同)
function ce(type,style){
var elem=document.createElement(type);
Object.assign(elem.style,style);
return elem;
}
var div1=ce("div");
var div2=ce("div");
var p=ce("p");
console.log(div1===div2); //false 每次生成的div都不同
2.单例模式
- 单例模式和工厂模式相反,每次生成的东西都是一样的,因为其返回的是全局的
- 经常用在类中,方法中实例化后赋值全局的属性,返回变量
使用情景1 组件封装时创建最大的容器
function createElem(){
if(!elem) elem=document.createElement("div");
return elem;
}
var a=createElem();
var b=createElem();
console.log(a===b); //true 因为第一次没有,创建之后,后面的不创建,返回的都是第一次的
使用情景2 类中实例化对象的获取
class Box{
static _instance
constructor(){
}
static getInstance(){
if(!Box._instance)Box._instance=new Box();
return Box._instance;
}
}
var a=Box.getInstance()
var b=Box.getInstance();
console.log(a===b);
使用情景2的复杂写法 类中实例化对象的获取,动态方法的使用不在需要实例使用
class Box{
constructor(){
}
static get instance(){
if(!Box._instance){
Object.defineProperty(Box,"_instance",{ //给Box类增加属性 相当于static _instance
value:new Box()
})
}
return Box._instance;
}
play(){
console.log("play");
}
run(){
console.log("run");
}
}
var a=Box.instance
var b=Box.instance;
console.log(a===b);
Box.instance.play(); //动态方法模仿静态方法的使用
Box.instance.run();
3.中介者模式
-
中介者模式的目的:实现代码的解耦(经常和单例模式来一起使用)
-
中介者模式实现方式,下面我用讲故事的方法来阐述
1.不完全解耦: 有客户A和客户B、中间人共3人,这两个客户都在中间人的办公楼中买卖房子。客户A拿出手机给中间人发了一个消息,中间人接收到这个消息后,拿出手机给
客户B发送一条消息,客户B接收到消息后,开始行动。
解释:客户A、客户B、中间人分别是类A,类B,类model(中介者类),html,在html中,类A和类B分别实例化后,成为类model的两个属性,
---A调用方法,方法中调用model的方法发送数据,model下的方法接收到,调用类B的方法发送消息,类B下的方法接收到消息2.完全解耦 :示例和不完全解耦大致相同,不同的是model收到数据后,向类B发送数据时,用的是事件的抛发,达到了完全解耦的效果
故事看完了,看看代码具体怎么实现
- HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module"> //引入客户A,客户B,客户C,中间人model
import A from "./js/A.js";
import B from "./js/B.js";
import C from "./js/C.js";
import Model from "./js/Model.js";
new C(); // C是完全解耦,是要new就能实现效果
Model.instance.a=new A(); //客户 A和B成为model的属性
Model.instance.b=new B();
Model.instance.a.run(); //客户A 调用其下方法
</script>
</body>
</html>
- 类A
import Model from "./Model.js";
export default class A{
constructor(){
}
run(){
Model.instance.data=100; //给中间人 model发送消息
}
}
- 类 model
export default class Model extends EventTarget{
_data=0;
constructor(){
super();
}
static get instance(){
if(!Model._instance){
Object.defineProperty(Model,"_instance",{
value:new Model()
})
}
return Model._instance;
}
set data(value){
this._data=value; //接收到类A发送的数据
Model.instance.b.play(value); //调用类B下的方法,向类B发送数据
var evt=new Event("data"); //向类C抛发事件,发送数据,实现完全解耦
this.dispatchEvent(evt);
}
get data(){
return this._data;
}
}
- 类 B
export default class B{
constructor(){
}
play(n){ //接收到类model(类A发送的)数据后,开始执行
console.log(n);
}
}
- 类C
import Model from "./Model.js";
export default class C{
constructor(){
Model.instance.addEventListener("data",e=>this.datahandler(e)); //侦听类model抛发出来的事件,获取其发送出来的数据
}
datahandler(e){
// console.log(Model.instance.data);
console.log(e);
}
}