当前位置: 首页 > news >正文

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()

效果

总结 

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

相关文章:

  • ubuntu 22.04 图文安装
  • Java使用Redis实现分页功能
  • 微服务中4种应对跨库Join的思路
  • 如何选择最适合的图纸加密软件?用户体验及性价比
  • 同一台宿主机上虚拟机CPU资源分配方式介绍
  • 【Redis实战】有MQ为啥不用?用Redis作消息队列!?Redis作消息队列使用方法及底层原理高级进阶
  • 剑指offer面试题16 反转链表
  • 【栈】150. 逆波兰表达式求值
  • 面向对象编程入门:掌握C++类的基础(1/3)
  • MCU中断控制
  • CSRNET图像修复,DNN
  • http协议与apache
  • STM32_ESP8266 连接阿里云 操作图解
  • CSS中伪元素和伪类的区别和作用?
  • Vue3实现带动画效果的tab栏切换
  • 【comparator, comparable】小总结
  • Apache Spark Streaming 使用实例
  • ECS应用管理最佳实践
  • Fastjson的基本使用方法大全
  • java概述
  • Java知识点总结(JavaIO-打印流)
  • js面向对象
  • oldjun 检测网站的经验
  • Puppeteer:浏览器控制器
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 通过git安装npm私有模块
  • 微服务入门【系列视频课程】
  • 一个项目push到多个远程Git仓库
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​批处理文件中的errorlevel用法
  • ​香农与信息论三大定律
  • ###C语言程序设计-----C语言学习(6)#
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • (C语言)共用体union的用法举例
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (简单) HDU 2612 Find a way,BFS。
  • (转)可以带来幸福的一本书
  • ***利用Ms05002溢出找“肉鸡
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .Net Memory Profiler的使用举例
  • .NET/C# 使窗口永不获得焦点
  • .net中生成excel后调整宽度
  • @Autowired 与@Resource的区别
  • @Autowired多个相同类型bean装配问题
  • @Data注解的作用
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [C#]C#学习笔记-CIL和动态程序集
  • [caffe(二)]Python加载训练caffe模型并进行测试1
  • [Effective C++读书笔记]0012_复制对象时勿忘其每一部分
  • [EFI]Dell Latitude-7400电脑 Hackintosh 黑苹果efi引导文件