组合模式
多个实例化对象的入口函数的一次性调用
功能
-
向 组合模式中 新增 要控制的 实例化对象, 已经存在的实例化对象 不会重复新增
-
向 组合模式中 删除 要控制的 实例化对象, 如果组合模式中没有的实例化对象 不不会执行删除操作
-
一键启动所有添加的 实例化对象
构造函数中 需要创建一个数组 存储 添加的实例化对象 构造函数中 需要函数方法1 新增 构造函数中 需要函数方法2 删除 构造函数中 需要函数方法3 执行
// 构造函数1
class Fun1 {
constructor() { }
init() {
this.ff11();
this.ff12();
this.ff13();
this.ff14();
}
ff11() { console.log('我是构造函数1的 函数方法1') };
ff12() { console.log('我是构造函数1的 函数方法2') };
ff13() { console.log('我是构造函数1的 函数方法3') };
ff14() { console.log('我是构造函数1的 函数方法4') };
}
// 构造函数2
class Fun2 {
constructor() { }
init() {
this.ff21();
this.ff22();
this.ff23();
}
ff21() { console.log('我是构造函数2的 函数方法1') };
ff22() { console.log('我是构造函数2的 函数方法2') };
ff23() { console.log('我是构造函数2的 函数方法3') };
}
// 构造函数3
class Fun3 {
constructor() { }
init() {
this.ff31();
this.ff32();
this.ff33();
this.ff34();
this.ff35();
this.ff36();
}
ff31() { console.log('我是构造函数3的 函数方法1') };
ff32() { console.log('我是构造函数3的 函数方法2') };
ff33() { console.log('我是构造函数3的 函数方法3') };
ff34() { console.log('我是构造函数3的 函数方法4') };
ff35() { console.log('我是构造函数3的 函数方法5') };
ff36() { console.log('我是构造函数3的 函数方法6') };
}
// 构造函数4
class Fun4 {
constructor() { }
init() {
this.ff41();
this.ff42();
}
ff41() { console.log('我是构造函数4的 函数方法1') };
ff42() { console.log('我是构造函数4的 函数方法2') };
}
// 利用构造函数1 创建 实例化对象
const obj1 = new Fun1();
console.log(obj1);
// 直接调用实例化对象的入口函数
// obj1.init();
// 利用构造函数2 创建 实例化对象
const obj2 = new Fun2();
console.log(obj2);
// 直接调用实例化对象的入口函数
// obj2.init();
// 利用构造函数3 创建 实例化对象
const obj3 = new Fun3();
console.log(obj3);
// 直接调用实例化对象的入口函数
// obj3.init();
// 利用构造函数4 创建 实例化对象
const obj4 = new Fun4();
console.log(obj4);
// 直接调用实例化对象的入口函数
// obj4.init();
// 组合模式
class CreateGroup{
// 构造器
constructor(){
// 定义一个数组 存储 要执行的实例化对象
this.arr = [] ;
}
// 新增
// 已经存在了不会再次向数组新增
// 实参个数不确定 使用合并运算符 以 数组的形式存储
add( ...objArr ){
// 循环遍历数组
objArr.forEach( item => {
// item 是 每一个要执行新增操作的实例化对象
// 向数组的末位新增 一个实例化对象
// 在数组this.arr 中 查询 如果数组中没有当前实例化对象 再 进行数组新增操作
if( this.arr.indexOf( item ) === -1 ) this.arr.push( item );
})
};
// 删除
delete( ...objArr ){
// 因为有数组坍塌问题 需要使用for循环 循环 objArr
// for( let i = 0 ; i <= objArr.length-1 ; i++ ){
// // i 是 objArr 中 存储的 要删除的实例化对象的索引下标
// // objArr[i] 是 要删除的实例化对象
// // 查询 原始数组中this.arr 中 有没有 要删除的实例化对象
// if( this.arr.indexOf( objArr[i] ) !== -1 ){
// // 如果查询结果不是-1 证明 原始数组中 有 要删除的实例化对象
// // 需要找到要删除的实例化对象 在 原始数组中对应的实例化对象的索引下标
// // let index = this.arr.indexOf( objArr[i] ) ;
// // 从 对应的索引下标index 开始 删除 1个单元
// this.arr.splice( this.arr.indexOf( objArr[i] ) , 1 );
// }
// }
// 因为有数组坍塌问题 使用 for循环 循环 this.arr
for( let i = 0 ; i <= this.arr.length-1 ; i++ ){
// i 是 原始数组的索引下标
// this.arr[i] 是 原始数组中 已经存储的 实例化对象
// 在 要删除的实例化对象数组objArr中 查询 已经存储的实例化对象this.arr[i]
if( objArr.indexOf( this.arr[i] ) !== -1 ){
// 如果查询结果不是-1 证明 当前存储的实例化对象 是 要删除的实例化对象
// 从 索引下标i 开始 删除一个单元
this.arr.splice( i , 1 );
// 为了防止数组坍塌的影响
// 在 触发删除操作 引起数组坍塌的单元位置 再次触发循环
i-- ;
}
}
};
// 清空
clear(){
// 直接赋值一个空数组
this.arr = [] ;
};
// 执行
// 调用所有添加的实例化对象的入口函数
execute(){
// 循环遍历每一个 this.arr 中 每一个实例化对象
// 调用入口函数 init
this.arr.forEach( item => {
// item 是 已经添加的实例化对象
// 调用 实例化对象中的入口函数init
item.init();
})
};
}
// 创建组合模式的实例化对象
const groupObj = new CreateGroup();
// 调用新增函数方法 向 数组中新增要执行的实例化对象
// groupObj.add( obj1 , obj2 );
// groupObj.add( obj3 , obj4 );
groupObj.add( obj1 , obj2 , obj3 , obj4 );
groupObj.add( obj1 , obj2 , obj3 );
// groupObj.add( obj4 );
// 调用函数方法 删除 已经添加的实例化对象
groupObj.delete( obj1 , obj2 );
// 调用函数方法 清空 已经添加的实例化对象
// groupObj.clear();
// 调用函数方法 执行 所有添加的实例化对象的入口函数
groupObj.execute();
console.log( groupObj );
观察者模式
观察者模式/发布订阅模式
当主体数据状态改变时 通知相关个体 触发执行对应的操作
如果个体状态发生改变 主体程序也要做相关的对应操作
实际项目操作中 需要 配合 双向数据绑定
主要组成部分
1, 消息盒子 本质是一个对象
对象的键名
事件类型
对象的键值
事件处理函数 以数组的形式存储
2, 新增
重复的事件处理函数 不要重复添加
3, 删除
已经存在的事件处理函数 再执行删除操作
4, 清空
赋值空对象
5, 执行
已经添加的事件处理函数 再执行操作
// 观察者模式 构造函数
class CreateObserver{
constructor(){
// 消息盒子 本质上是一个对象
this.msg = { } ;
}
// 新增函数
add( type , ...funArr ){
// 消息盒子this.msg中 如果事件类型不存在
// 也就是 当前时间类型 第一次新增事件处理函数
// 给消息黑子 直接添加 属性是事件类型 属性值是funArr 数组
if( this.msg[type] === undefined ){
// 在 消息盒子对象this.msg中 调用当前 事件类型
// 调用结果 如果 是 undefined 证明 当前 消息盒子中 没有这个事件类型
// 也就是 第一次新增事件类型和事件处理函数 直接新增就可以
this.msg[type] = funArr ;
}else{
// 在 消息盒子对象this.msg中 调用当前 事件类型
// 调用结果 如果 不是 undefined 证明 当前 消息盒子中 有这个事件类型
// 也就是 判断要添加的事件处理函数 是不是 已经存储在数组中
// 如估 数组中已经存储了当前事件处理函数 不能重复他添加已经存在的事件处理函数函数
// 循环遍历 数组funArr
funArr.forEach( item => {
// item 是 要新增的事件处理函数函数
if( this.msg[type].indexOf( item ) === -1 ){
// 已经存在的事件处理函数函数中没有当前要添加的事件处理函数
// 可以执行新增写入操作
this.msg[type].push( item );
}
})
}
};
// 删除函数
delete( type , ...funArr){
// 判断事件类型必须已经存在
if( this.msg[type] !== undefined ){
// 循环要删除的事件类型数组funArr
// 删除已经添加的事件类型数组this.msg[type]中对应的事件处理函数
funArr.forEach( item => {
// item 是 要删除的事件处理函数
// 如果要删除的事件处理函数已经存在 再执行删除操作
if( this.msg[type].indexOf( item ) !== -1 ){
this.msg[type].splice( this.msg[type].indexOf( item ) , 1);
}
})
}
};
// 清空函数
clear( type ){
// 如果没有给 clear() 函数方法 输入实参
// type存储 undefined 也就是 this.msg 赋值存储 空对象
if( type === undefined ){
// 给 消息盒子this.msg 赋值存储 空对象
this.msg = {} ;
// type 输入了 参数
// 给 参数对应的事件类型 存储 空数组
}else{
// 如果当前type中存储的事件类型存在 再执行清空这个事件类型操作
if( this.msg[type] !== undefined ){
// 对应的事件类型赋值存储空数组
this.msg[type] = [] ;
}
}
};
// 执行函数
execute(type , ...funArr){
// 判断 事件类型存在
if( this.msg[type] !== undefined ){
// 判断事件处理函数是不是已经存储的事件处理函数函数
funArr.forEach( item => {
if( this.msg[type].indexOf( item ) !== -1 ){
// 如果事件处理函数已经存在 调用执行
item();
}
})
}
};
}
// 创建实例化对象
const observerObj = new CreateObserver();
// 调用函数新增事件类型和事件处理函数
observerObj.add( 'wenzhang' , wz1 , wz3 , wz4 );
observerObj.add( 'wenzhang' , wz2 , wz3 , wz4 );
observerObj.add( 'game' , game1 , game2 , game3 , game4 );
observerObj.add( 'cj' , cj1 , cj2 , cj3 , cj4 , cj5 , cj6 );
observerObj.add( 'cs' , cs1 , cs2 , cs3 , cs4 , cs5 );
// 调用函数删除事件处理函数
observerObj.delete( 'cj' , cs1 , cj1 , cj4 );
observerObj.delete( 'cs' , cs1 , cs2 , cs3 , cs4 );
// 清空存储的所有事件类型和事件处理函数
// observerObj.clear();
// observerObj.clear('game');
// observerObj.clear('abc');
// 调用函数执行对饮的事件处理函数
observerObj.execute('game' , game1 , game4 , cj3);
observerObj.execute('cs' , cs1 , cs2 , cs3 , cs4 , cs5);
console.log( observerObj );
// 提前定义好函数程序
// 发布文章
function wz1(){ console.log( '推广发送的文章1' ) };
function wz2(){ console.log( '推广发送的文章2' ) };
function wz3(){ console.log( '推广发送的文章3' ) };
function wz4(){ console.log( '推广发送的文章4' ) };
function wz5(){ console.log( '推广发送的文章5' ) };
// 小游戏
function game1(){ console.log( '推广发送的游戏1' ) };
function game2(){ console.log( '推广发送的游戏2' ) };
function game3(){ console.log( '推广发送的游戏3' ) };
function game4(){ console.log( '推广发送的游戏4' ) };
// 抽奖
function cj1(){ console.log( '推广发送的抽奖1' ) };
function cj2(){ console.log( '推广发送的抽奖2' ) };
function cj3(){ console.log( '推广发送的抽奖3' ) };
function cj4(){ console.log( '推广发送的抽奖4' ) };
function cj5(){ console.log( '推广发送的抽奖5' ) };
function cj6(){ console.log( '推广发送的抽奖6' ) };
// 心理测试
function cs1(){ console.log( '推广发送的心里测试1' ) };
function cs2(){ console.log( '推广发送的心里测试2' ) };
function cs3(){ console.log( '推广发送的心里测试3' ) };
function cs4(){ console.log( '推广发送的心里测试4' ) };
function cs5(){ console.log( '推广发送的心里测试5' ) };