JavaScript 设计模式之组合模式

组合模式

在我们日常中肯呢个会将一个表单用这种模式来创建

const Car = function () { }
Car.prototype.getName = function () { throw new Error("需要重写该方法")
}
Car.prototype.getPrice = function () {throw new Error("需要重写该方法")
}
const Benz = function () { }
// 继承Car
Benz.prototype = new Car()
// 重写getName方法
Benz.prototype.getName = function () {return 'Benz'
}
const b = new Benz()
console.log(b.getName()) // Benz
console.log(b.getPrice()) // 需要重写该方法

先写一个基类,再继承该基类

const Benz = function (name, price) {Car.call(this)this.name = namethis.price = price
}
Benz.prototype = new Car
Benz.prototype.getPrice = function () {return this.price
}
Benz.prototype.getName = function () {return this.name
}
const benz = new Benz('奔驰', 50)
console.log(benz.getName()) // 输出:奔驰
console.log(benz.getPrice()) // 输出:50
const bmw = new Benz('宝马', 100)
console.log(bmw.getPrice()) // 输出:100

构建一个 Form 表单

首先我们创建一个基类

定义


const Base = function () { this.children = []this.element = null
}
Base.prototype = {init: function () {throw new Error('必须重写该方法')},add: function () {throw new Error('必须重写该方法')},remove: function () {throw new Error('必须重写该方法')},get: function () {throw new Error('必须重写该方法')}
}

接下来创建一个容器


const FormItem = function (id,parent) {Base.call(this)this.id = idthis.parent = parentthis.init()
}
FormItem.prototype = new Base()
FormItem.prototype.init = function () {this.element = document.querySelector('#form')this.element.id = this.id
}
FormItem.prototype.add = function (child) {this.children.push(child)this.element.appendChild(child.getDom())return this
}
FormItem.prototype.getDom = function () {return this.element
}
FormItem.prototype.show = function () { this.parent.appendChild(this. Element)
}

注意,这里的 show 方法就是用来将所有的 dom 追加到页面上

下面创建一系列的 form 相关 item 及一些dom


const FieldsetItem = function (selector, label) {Base.call(this)this.selector = selectorthis.label = labelthis.init()
}
FieldsetItem.prototype = new Base()
FieldsetItem.prototype.init = function () {this.element = document.createElement('fieldset')const legend = document.createElement('legend')legend.innerHTML = this.labelthis.element.appendChild(legend)
}
FieldsetItem.prototype.add = function (child) {this.children.push(child)this.element.appendChild(child.getDom())return this
}
FieldsetItem.prototype.getDom = function () {return this. Element
}const Group = function () {Base.call(this)this.init()
}
Group.prototype = new Base()
Group.prototype.init = function () {this.element = document.createElement('div')this.element.className = 'group'
}
Group.prototype.add = function (child) {this.children.push(child)this.element.appendChild(child.getDom())return this
}
Group.prototype.getDom = function () {return this.element
}const LabelItem = function (name, label) {Base.call(this)this.name = namethis.label = labelthis.init()
}
LabelItem.prototype = new Base()
LabelItem.prototype.init = function () {this.element = document.createElement('label')this.element.innerHTML = this.labelthis.element.htmlFor = this.name
}
LabelItem.prototype.add = function (child) {// 这里不需要添加,因为label后面直接跟输入框return this
}
LabelItem.prototype.getDom = function () {return this.element
}const InputItem = function (name) {Base.call(this)this.name = namethis.init()
}
InputItem.prototype = new Base()
InputItem.prototype.init = function () {this.element = document.createElement('input')this.element.name = this.namethis.element.style.marginLeft = '5px'
}
InputItem.prototype.add = function (child) {// 这里不需要添加,因为输入框后面直接跟标签return this
}
InputItem.prototype.getDom = function () {return this.element
}const CheckboxItem = function (name, value, label) {Base.call(this)this.name = namethis.value = valuethis.label = labelthis.init()
}
CheckboxItem.prototype = new Base()
CheckboxItem.prototype.init = function () {const span = document.createElement('span')this.element = document.createElement('label')const input = document.createElement('input')input.type = 'checkbox'span.innerHTML = this.labelinput.value = this.valueinput.style.marginRight = '5px'this.element.appendChild(input)this.element.appendChild(span)
}
CheckboxItem.prototype.add = function (child) {
}
CheckboxItem.prototype.getDom = function () {return this.element
}const SpanItem = function (name) {Base.call(this)this.name = namethis.init()
}
SpanItem.prototype = new Base()
SpanItem.prototype.init = function () {this.element = document.createElement('span')this.element.innerHTML = this.namethis.element.style.marginLeft = '5px'
}
SpanItem.prototype.add = function (child) {// 这里不需要添加,因为span前面直接跟输入框return this
}
SpanItem.prototype.getDom = function () {return this. Element
}

使用 

假使页面中存在 dom 

 <form id="form"></form><div id="content"></div>

js

var form = new FormItem('form', document.querySelector('#content'))
form.add(new FieldsetItem('account', '账号').add(new Group().add(new LabelItem('user_name', '用户名:')).add(new InputItem('user_name')).add(new SpanItem('4 到 6 位数字或字母'))
).add(new Group().add(new LabelItem('user_pwd', '密&emsp;码:')).add(new InputItem('user_pwd')).add(new SpanItem('6 到 12 位数字或字母'))
).add(new Group().add(new CheckboxItem('remember', true, '是否记住'))
)).show()

效果

总结 

组合模式能够给我们提供一个清晰的组成结构。组合对象类通过继承同一个父类使其具有统一的方法,这样也方便了我们统一管理与使用,当然此时单体成员与组合体成员行为表现就比较一致了,这也模糊了简单对象与组合对象的区别

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/693408.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

突破性创新:OpenAI推出Sora视频模型,预示视频制作技术的未来已到来!

一、前言 此页面上的所有视频均由 Sora 直接生成&#xff0c;未经修改。 OpenAI - Sora is an AI model that can create realistic and imaginative scenes from text instructions. 2024 年 2 月 16 日&#xff0c;OpenAI 发布 AI 视频模型 Sora&#xff0c;60 秒的一镜到底…

XML Map 端口进阶篇——常用关键字和格式化器详解

XML Map 端口是用于在不同XML之间建立关系映射的工具&#xff0c;允许通过拖拽操作实现源XML和目标 XML之间的数据字段映射&#xff0c;除此之外&#xff0c;XML Map 端口还提供了其它丰富多彩的功能&#xff0c;使用户能够更加灵活和高效的处理XML 数据映射任务&#xff0c;让…

以程序员的视角,看前后端分离的是否必要?

Hello&#xff0c;我是贝格前端工场&#xff0c;本篇分享一个老生常谈的话题&#xff0c;前后端分离是必然趋势&#xff0c;但也是要区分具体的场景&#xff0c;欢迎探讨&#xff0c;关注&#xff0c;有前端开发需求可以私信我&#xff0c;上车了。 一、什么是前后端分离和不分…

Bert-VITS-2 效果挺好的声音克隆工具

持中日英三语训练和推理。内置干声分离&#xff0c;切割和标注工具&#xff0c;开箱即用。请点下载量右边的符号查看镜像所对应的具体版本号。 教程地址&#xff1a; sjj​​​​​​​CodeWithGPU | 能复现才是好算法CodeWithGPU | GitHub AI算法复现社区&#xff0c;能复现…

分享一个背英语单词的方法

目录 前言 乱序记忆法 结语 前言 这是我现在正在用的背单词方法&#xff0c;我觉得是不错的&#xff0c;分享一下&#xff0c;希望对你有帮助。也欢迎评论点赞哟。 乱序记忆法 这种方法需要我们准备好纸&#xff0c;是需要我们动笔的。我坚持认为&#xff0c;动笔去记单词的…

人工智能专题: Sora,世界模拟器的视频生成器

今天分享的是人工智能系列深度研究报告&#xff1a;《人工智能专题&#xff1a; Sora&#xff0c;世界模拟器的视频生成器》。 &#xff08;报告出品方&#xff1a;华泰证券&#xff09; 报告共计&#xff1a;16页 来源&#xff1a;人工智能学派 Sora 能做什么&#xff1f;…

苍穹外卖——第一天nginx

放到全是英文路径的打不开 到安装路径进入cmd&#xff0c;输入nginx -t nginx: the configuration file E:\Astudy\nginx-1.20.2/conf/nginx.conf syntax is ok nginx: [emerg] bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbid…

Fiddler工具 — 18.Fiddler抓包HTTPS请求(一)

1、Fiddler抓取HTTPS过程 第一步&#xff1a;Fiddler截获客户端发送给服务器的HTTPS请求&#xff0c;Fiddler伪装成客户端向服务器发送请求进行握手 。 第二步&#xff1a;服务器发回相应&#xff0c;Fiddler获取到服务器的CA证书&#xff0c; 用根证书&#xff08;这里的根证…

c# Contains方法-检查集合中是否包含指定的元素

Contains 是 .NET 集合框架中许多集合类&#xff08;如 List、Array、HashSet 等&#xff09;提供的一种方法&#xff0c;用于检查集合中是否包含指定的元素。对于 List<int> 类型&#xff0c;Contains 方法会遍历列表中的所有元素&#xff0c;并判断传入的方法参数是否存…

UI自动化之使用poco进行元素的唯一定位

直接选择&#xff1a; 1.poco(text买入).click() 2.poco("android.widget.ImageView").click()相对选择、空间选择&#xff1a; 3.poco(text/name).parent().child()[0].click()正则表达式&#xff1a; 4.listpoco(textMatches".*ETF")今天主要想记录下…

c编译器学习05:与chibicc类似的minilisp编译器(待续)

minilisp项目介绍 项目地址&#xff1a;https://github.com/rui314/minilisp 作者也是rui314&#xff0c;commits也是按照模块开发提交的。 minilisp只有一个代码文件&#xff1a;https://github.com/rui314/minilisp/blob/master/minilisp.c 加注释也只有996行。 代码结构&a…

《剑指Offer》笔记题解思路技巧优化 Java版本——新版leetcode_Part_5

《剑指Offer》笔记&题解&思路&技巧&优化_Part_5 &#x1f60d;&#x1f60d;&#x1f60d; 相知&#x1f64c;&#x1f64c;&#x1f64c; 相识&#x1f622;&#x1f622;&#x1f622; 开始刷题&#x1f7e2;1. LCR 158. 库存管理 II——数组中出现次数超过一…

vue.js前端框架应用案例

Vue.js 是一种流行的前端框架&#xff0c;它可以帮助开发者构建单页应用&#xff08;SPA&#xff09;和复杂的用户界面。以下是几个 Vue.js 的案例&#xff0c;涵盖了不同领域的应用&#xff1a; Vue.js 官方文档&#xff1a;Vue.js 的官方文档本身就是一个使用 Vue.js 构建的…

SQL数据库基础语法-增删改

SQL数据库基础语法-增删改 数据库是 ​ “按照数据结构来组织、存储和管理数据的仓库”。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。 GeekSec专注技能竞赛培训5年&#xff0c;包含网络建设与运维和信息安全管理与评估两大赛项&#xff0c;…

synchronized原理Callable接口

synchronized原理 特点 1.synchronized既是一个悲观锁,又是个乐观锁&#xff0c;自适应的&#xff01; synchronized默认是乐观锁,但是如果发现锁竞争比较激烈,就会变成悲观锁!!2.synchronized既是轻量级锁,又是一个重量级锁,自适应&#xff01; synchronized默认是轻量…

字符串算法(算法竞赛)--最小表示法与最详细的字符串哈希

1、B站视频链接&#xff1a;F01 最小表示法_哔哩哔哩_bilibili 题目链接&#xff1a;【模板】最小表示法 - 洛谷 #include <bits/stdc.h> using namespace std; const int N7e5; int n; int s[N];int get_min(){for(int i1;i<n;i)s[ni]s[i];//字符串复制一倍int i1,j…

png图片转换tif图片格式(只有目标和背景两种颜色)

在这里以红色目标为例子&#xff0c;我的背景里面有很多颜色&#xff0c;但是我只想要红色的目标部分 &#xff08;注&#xff1a;这里的程序是将图片中的红色目标提取出来&#xff0c;其余背景全是黑色&#xff0c;如果想要其他颜色&#xff0c;请根据阈值自行修改&#xff09…

车载软件架构Adaptive AUTOSAR —— 身份和访问管理和加密技术

车载软件架构Adaptive AUTOSAR —— 身份和访问管理和加密技术 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。…

辽宁博学优晨教育科技有限公司视频剪辑培训靠谱吗?

在数字媒体日益繁荣的今天&#xff0c;视频剪辑已成为一项炙手可热的技能。不少培训机构纷纷涉足这一领域&#xff0c;辽宁博学优晨教育科技有限公司便是其中之一。然而&#xff0c;面对众多的选择&#xff0c;很多人不禁要问&#xff1a;辽宁博学优晨教育科技有限公司的视频剪…

android密集架移动动画效果开发

机缘 因公司需要开发密集架相关项目,涉及相关项目需求设计,市场上并未有相关动画效果流出,基于设计开发相关需求 多列密集架情况: 密集架固定列在最左侧密集架固定列在最右侧密集架固定列在最中间收获 最终完成初步效果 实例展示: android密集架移动效果 部分核心代码…