组合模式

2020-10-31  本文已影响0人  小宇cool

1. 组合模式

1.1 组合模式的定义

组合模式(Composite): 又称部分-整体模式, 将对象组合成树形结构以表示"部分-整体"的层次结构,

组合模式使得用户单个对象和组合对象的使用具有一致性.

简单来说就是不管你是操作单个东西, 还是操作多个东西操作方式都是一样的, 例如我们生活中淘宝购物车付款, 不管是一个商品还是多个商品都是一次性付款, 清除硬文件, 不管是删除单个文件还是一个包含多个文件的文件夹都是一样的操作.

1.2 组合模式的作用

  1. 降低单个对象和复杂对象的使用上不同, 使得他们的使用具有一致性.
  2. 模糊单个对象和复杂对象的概念, 减轻操作复杂对象的难度.

组合模式允许我们能统一的处理单个对象和多个对象, 这意味着无论是一个对象还是一千个对象

我们都能以同样的行为描述.

1.3 使用场景

一看到树形结构,我们第一个想到的就是DOM树结构,DOM树天生就是属于树形结构.所以我们在使用统一

DOM节点操作方式时, 就是一个典型的组合模式案列

在Jquery中, 当我们在一个节点或多个节点上应用方法时,我们都能以相同的方式来选择并返回Jquery对象

//jquery的addClass不管是操作一个节点还是多个节点写法都是一样的
// 这是一个典型的组合模式的实现
$('.container').addClass('age');
$('box').addClass('active');
$('box').css('color','red');
// 下面我们使用js简单模拟一下
 function $(selector){
     let eleList =  selector instanceof NodeList 
         ?  [...selector] 
         :  document.querySelectorAll(selector);
     return {
         addClass(classname){
             eleList.forEach((ele) =>{
                 ele.classList.add(classname)
             })
         },
         css(attr,value){
             eleList.forEach((ele,index) =>ele.style[attr] = value )
         }
     }
 }
// 场景二 模拟一个简答的输出点餐订单场景
// 总订单包括若干大类, 每个大类都有对应的若干商品
/* 
    抽象类 没有实例化的价值, 仅仅作为父类继承用, 作用是统一APi接口, 并提醒
    规避错误, 这也是我们之前说的抽象工程的作用
 */
class AbsMenu {
    constructor() {}
    add() {
        throw new Error("如需使用请重写!");
    }
    print() {
        throw new Error("如需使用请重写!");
    }
}
// 创建最基础的商品类 
class Item extends AbsMenu {
    constructor(name, price, taste) {
        super()
        this.name = name;
        this.price = price;
        this.taste = taste;
    }
    print() {
        console.log(this.name + ":" + this.taste + "-----" + this.price + "元");
    }
}
// 创建大类
class Category extends AbsMenu {
    constructor(name) {
        super()
        this.children = [];
        this.name = name
    }
    add(item) {
        this.children.push(item)
        return this
    }
    print() {
        console.group(this.name)
        this.children.forEach(v => v.print())
        console.groupEnd()
    }
}
// 创建主订单
class Menu extends AbsMenu{
    constructor(id){
        super()
        this.id = id;
        this.children = []

    }
    add(category) {
        console.log(category);
        this.children.push(category)
        return this
    }
    print() {
        console.group(this.id+'的菜单')
        this.children.forEach(v => v.print())
        console.groupEnd()
    }
}
let main =  new Category('主菜')
        .add(new Item('麻辣小龙虾', 40, '变态辣'))
        .add(new Item('麻婆豆腐', 20, '微辣'))
        .add(new Item('千叶豆腐', 15, '清淡'))
let sweetmeats = new Category('甜品')
        .add(new Item('豆花', 40, '非常甜'))
        .add(new Item('冰淇淋', 20, '奶油加多'))
        .add(new Item('小蛋糕', 15, '清淡'))

    let menu = new Menu('12').add(main).add(sweetmeats);
    menu.print()

控制台打印如下所示

image-20201031150446994.png

总结: 想构建整体-部分的结构时使用, 忽略单个对象和多个对象的使用区别, 统一调用接口.组合模式使得单个对象和组合对象的使用具有一致性.

上一篇下一篇

猜你喜欢

热点阅读