吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 112|回复: 0
收起左侧

[学习记录] 一文读懂组合模式

[复制链接]
winsdomWindy 发表于 2025-3-19 20:15

组合模式又称整体部分模式,将对象组合成树形结构以表示部分-整体的关系。客户可以统一对待组合对象和叶子对象。

组合模式中对象分为组合对象和叶子对象,组合对象包含叶子对象。叶子对象是最小的对象单元。

组合模式的使用场景

  • 表示对象的部分-整体层次结构。组合模式可以方便地构造一棵树来表示对象的部分-整体结构。特别是我们在开发期间不确定这棵树到底存在多少层次的时候。在树的构造最终完成之后,只需要通过请求树的最顶层对象,便能对整棵树做统一的操作。
  • 客户希望统一对待树中的所有对象。组合模式使客户可以忽略组合对象和叶对象的区别,客户在面对这棵树的时候,不用关心当前正在处理的对象是组合对象还是叶对象,也就不用写一堆if、else语句来分别处理它们。组合对象和叶对象会各自做自己正确的事情

示例:表单

表单可以很好地使用组合模式,container元素作为根对象,container下面可以有n个表单,在每个表单下面可以存在n个表单控件,每个控件下面存在label和具体的控件,这样就形成了一个树形结构。

// Container是一个抽象类用于被容器类和叶子类继承
// 将多个部分组成一个整体
// 将对象组合成树形结构以表示部分整体的层次结构。组合模式让用户对单个对象和组合对象的使用具有一致性。

class Container{
  constructor() {
    this.children = [];
    this.element = null;
  }

  init() {
    throw new Error('请重写init方法');
  }

  add(child) {
    this.children.push(child);
    this.element.appendChild(child.element);
    return this;
  }
}

class CreateForm extends Container{
  constructor(id,method,action,parent) {
    super();
    this.id = id || '';
    this.method = method || 'get';
    this.action = action || '';
    this.parent = parent || document.body;
    this.init();
  }
  init(){
    this.element = document.createElement('form');
    this.element.id = this.id;
    this.element.method = this.method;
    this.element.action = this.action;
  }
  show(){
    this.parent.appendChild(this.element);
  }
}

class CreateLine extends Container{
  constructor(className){
    super();
    this.className = className === undefined ? 'form-line' : 'form-line' + className;
    this.init();
  }
  init(){
    this.element = document.createElement('div');
    this.element.calssName = this.className;
  }
}

class CreateLabel extends Container{
  constructor(text, forName){
    super();
    this.text = text || '';
    this.forName = forName || '';
    this.init();
  }
  init(){
    this.element = document.createElement('label');
    this.element.setAttribute('for', this.forName);
    this.element.innerHTML = this.text;
  }

}

class CreateInput extends Container {
  constructor(type, id, name, defaultValue){
    super();
    this.type = type || '';
    this.id = id || '';
    this.name = name || '';
    this.defaultValue = defaultValue || '';
    this.init();
  }
  init(){
     this.element = document.createElement('input');
    this.element.type = this.type;
    this.element.id = this.id;
    this.element.name = this.name;
    this.element.value = this.defaultValue;
  }
  add(){
    throw new Error('不能添加子节点');
  }
}

let form  = new CreateForm('owner-form', 'get', '/aaa.html', document.body);
let userLine = new CreateLine().add(new CreateLabel('用户名', 'user')).add(new CreateInput('text', 'user', 'user'));
let pwdLine = new CreateLine().add(new CreateLabel('密码', 'pwd')).add(new CreateLabel('password', 'pwd', 'pwd')).add(new CreateInput('password', 'pwd', 'pwd'));

组合模式优点

  • 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次。它让客户端忽略了层次的差异,方便对整个层次结构进行控制。
  • 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。
  • 在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合开闭原则。
  • 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案。通过叶子对象和容器对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。

组合模式缺点

在增加新构件时很难对容器中的构件类型进行限制。有时希望一个容器中只能有某些特定类型的对象,例如在某个文件夹中只能包含文本文件。使用组合模式时,不能依赖类型系统来施加这些约束,因为它们都来自相同的抽象层。在这种情况下,必须通过在运行时进行类型检查来实现,这个实现过程较为复杂。

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-3-31 01:14

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表