代码要写成别人看不懂的样子(七)

海康Visionmaster-全局脚本:VM 加载方案后自动执行 的方法,如何让VM在方案加载后自动执行流程? 阅读详情

本篇文章参考书籍《JavaScript设计模式》–张容铭

前言

  来了各位,本节整个硬活,组合模式,这个模式在应对复杂需要的时候有超高的灵活性,举个例子,乐高大家都玩过吧,各种各样的模型都能拼。乐高的拼装有个特点,一块积木上面是一个一个的小圆珠体,下面是可以衔接圆柱体的卡槽。
在这里插入图片描述
  通过不同的组合我们可以拼出很多我们像要的东西,只有想不到的需求,没有实现不了的方案。

注意事项

  使用组合模式的时候,需要有两点注意:

  1. 所有接口要统一,所有类都要继承于一个虚拟父类(这一点保证所有积木都可以拼接在一起)
  2. 叶子节点的子类不允许再进行组合(类似下图中红色区域,该子类上面不需要再组合其他东西了,所有不需要再有圆柱体了)

在这里插入图片描述

组合模式

1.同一父类

  首先要满足所有子类都继承于一个虚拟父类。下面我们创建一个关于新闻的组合模式。

var News = function() {
	//子组件容器
	this.children = [];
	//当前组件元素
	this.element = null;
}
News.prototype = {
	init: function() {
		throw new Error('重写方法');
	},
	add: function() {
		throw new Error('重写方法');
	},
	getElement: function() {
		throw new Error('重写方法');
	}
}

2.组合需要有容器

  所有子类是放在这个容器当中的。

//容器构造类函数
var Container = function(id, parent) {
	//构造函数继承父类
	News.call(this);
	//模块id
	this.id = id;
	//模块父容器
	this.init();
}
//寄生组合继承
function inheritPrototype(subType, superType){
    let prototype = Object(superType.prototype); //创建对象
    prototype.constructor = subType; //增强对象
    subType.prototype = prototype; //指定对象
}
inheritPrototype(Container, News);
//构建方法
Container.prototype.init = function() {
	this.element = document.createELement('ul');
	this.element.id = this.id;
	this.element.className = 'new-container';
}
//添加子元素方法
Container.prorotype.add = function(child) {
	//在子元素容器中插入子元素
	this.children.push(child);
	//插入当前组件元素树中
	this.element.appendChild(child.getElement());
	return this;
}
//获取当前元素方法
Container.prototype.getElement = function() {
	return this.element;
}
//显示方法
Container.prototype.show = function() {
	this.parent.appendChild(this.element);
}

  下一层级构造方式与上面类似。

//下一层级成员
var Item = function(classname) {
	News.call(this);
	this.classname = classname || '';
	this.init();
}
inheritPrototype(Item, News);
Item.prototype.init = function(child) {
	this.element = document.createElement('li');
	this.element.calssName = this.classname;
}
Item.prototype.add = function(child) {
	//在子元素容器中插入子元素
	this.children.push(child);
	//插入当前组件元素树中
	this.element.appendChild(child.getElement());
	return this;
}
Item.prototype.getElement = function() {
	return this.element;
}
var NewsGroup = function(calssname) {
	News.call(this);
	this.classname = classname || '';
	this.init();
}
inheritPrototype(NewsGroup, News);
NewsGroup.prototype.init = function() {
	this.element = document.createElement('div');
	this.element.calssName = this.classname;
}
NewsGroup.prototype.add = function(child) {
	//在子元素容器中插入子元素
	this.children.push(child);
	//插入当前组件元素树中
	this.element.appendChild(child.getElement());
	return this;
}
NewsGroup.prototype.getElement = function() {
	return this.element;
}

3.创建子类成员

  容器造好之后,我们要创建每一个叶子节点类

var ImageNews = function(url, href, calssname) {
	News.call(this);
	this.url = url || '';
	this.href = href || '#';
	this.calssname = calssname || 'normal';
	this.init();
}
inheritPrototype(ImageNews, News);
ImageNews.prototype.init = function() {
	this.element = document.createElement('a');
	var Img = new Image();
	img.src = this.url;
	this.element.appendChild(img);
	this.element.classname = 'image-news ' + this.calssname;
	this.element.href = this.href;
}
ImageNews.prototype.add = function() {}
ImageNews.prototype.getElement = function() {
	return this.element;
}

var IconNews = function(text, href, type) {
	News.call(this);
	this.text = text || '';
	this.href = href || '#';
	this.type = type || 'video';
	this.init();
}
inheritPrototype(IconNews, News);
IconNews.prototype.init = function() {
	this.element = document.createElement('a');
	this.element.innerHTML = this.text;
	this.element.href = this.href;
	this.element.classname = 'icon ' + this.type;
}
ImageNews.prototype.add = function() {}
ImageNews.prototype.getElement = function() {
	return this.element;
}

var EasyNews = function(text, href) {
	News.call(this);
	this.text = text || '';
	this.href = href || '#';
	this.init();
}
inheritPrototype(EasyNews, News);
EasyNews.prototype.init = function() {
	this.element = document.createElement('a');
	this.element.innerHTML = this.text;
	this.element.href = this.href;
	this.element.classname = 'text ';
}
EasyNews.prototype.add = function() {}
EasyNews.prototype.getElement = function() {
	return this.element;
}

var TypeNews = function(text, href, type, pos) {
	News.call(this);
	this.text = text || '';
	this.href = href || '#';
	this.type = type || '';
	this.pos = pos || 'left';
	this.init();
}
inheritPrototype(TypeNews, News);
TypeNews.prototype.init = function() {
	this.element = document.createElement('a');
	if(this.pos = 'left') {
		this.element.innerHTML = '[' + this.type + ']' + this.text;
	} else {
		this.element.innerHTML =  this.text + '[' + this.type + ']';
	}
	this.element.href = this.href;
	this.element.classname = 'text ';
}

TypeNews.prototype.add = function() {}
TypeNews.prototype.getElement = function() {
	return this.element;
}

4.创建一个完整的类

  新闻类模块创建完成了,使用时需要使用 add 方法,像一棵树一样,一层一层的创建。

var newsl = new Container('news', document.body);
newsl.add(
	new Item('normal').add(
		new IconNews('1024程序员节,你coding了嘛', '#', 'video')
	)
).add(
	new Item('normal').add(
		new IconNews('双十一,你冲了吗', '#', 'live')
	)
).add(
	new Item('normal').add(
		new NewsGroup('has-img').add(
			new ImageNews('img/1.jpg', '#', 'small')
		).add(
			new EasyNews('湖人总冠军', '#')
		)
	)
).add(
	new Item('normal').add(
		new TypeNews('詹姆斯球鞋冠军配色', '#', 'NBA', 'left')
	)
).add(
	new Item('normal').add(
		new TypeNews('易建联生日快乐', '#', 'CBA', 'Right')
	)
).show();

  创建的每一条新闻都是一个独立的个体,互不影响,避免相互间的耦合,同时也增强了组合后模块的复杂性,以后不论有什么样的需求,只要做出相应的组合就可以轻松完成。

5.表单当中更灵活

  平常我们使用组合模式最多的地方就是表单提交,这一部分因为每一项都要求独立,且不同项目的表单都有点差异,所以很适合用组合模式。

  做法和上面的一样,先创建一个基类 Base ,然后创建三个组合类 FromItem , FieldsetItem , Group , 还有成员类 InputItem , LabelItem , SpanItem , TextareaItem 。

var form = new FromItem('FromItem', document.body);
form.add(
	new FieldsetItem('account', '账号').add(
		new Group().add(
			new LabelItem('user_name', '用户名');
		).add(
			newInputItem('user_name');
		).add(
			new SpanItem('4到6位数字或字母');
		)
	).add(
		new Group().add(
			new LabelItem('user_password', '密 码:')
		).add(
			new InputItem('user_password')
		).add(
			new SpanItem('6到12位数字或密码')
		)
	)
).add(
	//...
).show();

  组合模式刚上手有点乱,不过核心思想还是比较清晰明确的,把需求拆分成一个一个子类,让所有子类继承一个虚拟父类就可以了。之前问过一位高人,如何才能写好代码,前辈指点:“ 惟手熟尔 ”。设计模式初学的时候,一定要多用,用的多,才能记得住。




第3.4章 机器人第三方库实战总结(四):G2O优化库从入门到实战(附SLAM实例代码) 自定义边同样是满足复杂应用需求的重要手段。自定义边时,需要明确边所连接的顶点类型以及边所表示的误差项的计算方式。假设我们要定义一条边,用于约束两个上述自定义顶点之间的相对位姿和传感器偏移量关系。我们可以这样定义边类:public:// 计算误差// 计算雅可比矩阵// 读盘和存盘函数,这里暂不实现。 阅读详情

相关推荐

Infineon MOSFET开关损耗计算实战指南

本文是英飞凌MOSFET开关损耗计算的实战指南。针对MOSFET发热问题,文章深入剖析了开关损耗的产生机理,并基于Infineon数据手册的关键参数,手把手推导了开通与关断损耗的工程计算公式。同时,指南强调了栅极电阻、寄生参数等实际因素对损耗的影响,并提供了从理论计算到实测优化的完整路径,帮助工程师精准评估与优化电源设计。

weixin_29212867的博客 442

让你的javascript代码高大上

1,创造简短的写法 你可以这么写: 1 var slice = Array.prototype.slice; 2 slice.call(arguments); //转化成数组 也可以这么写:(ie9+) 1 var unboundSlice = Array.prototype.slice; 2 var slice = Function.prototype.call.bind(unbo...

Yveda_csdn的博客 384

An工具介绍之摄像头

An工具介绍之摄像头

人生得意须尽欢 6185

代码要写成别人看不懂的样子(一)

本篇文章参考以下博文 文章目录前言 前言   最近读了一本书,张容铭老师的 《JavaScript设计模式》 ,书中提到的编码模式,编码风格,让我想起了我刚学 JS 的时候,特别向往像大神一样,全篇没什么 div 罗列,都是方法或者构造函数之类的东西,一顿操作后, body 里面只要添加一个 <div id=“demo”> ,大功告成。   逼格满满有没有,当时就想,什么时候我也能这样,别人看不懂我的代码,所有的事情不用自己手写,只要给一个容器,然后执行函数就

不见浅诗的博客 1713

滤波算法-呼吸心跳信号检测方法(四)

呼吸心跳信号检测系列文章:信号滤波处理

yjh_2019的博客 6269

(南京观海微电子)——GH700X调试指南--SPI 接口+LVDS-测试盒使用方法

1表示OTP完成后,读取烧录值是否一致来判断是否烧录成功,2表示同时检测VCOM是否一致以及烧录次数是否增加,3表示不做任何检测,由用于自行在程序中判断。[格式]:SetFindVcomEn (<开启或关闭>),ON表示开启VCOM搜寻,默认是开启的,只要使能OTP烧录,按OTP按键则进行VCOM查询;[功能]:OTP完成检测类别,用于设置OTP完成后检测OTP次数还是OTP值来判断OTP是否成功。[功能]:用于设置VCOM查询使能,比如需要烧全代码而不需要对VCOM查询时,可以禁止VCOM查询。

m0_75095200的博客 1664

代码要写成别人看不懂的样子(二)

文章目录前言前期准备如何才能让别人看不懂1.四两拨千斤2.指桑骂槐 前言   上一期我们,浅尝辄止,稍微介绍了下代码如何写才能更高级,更有内涵,主要是需要配合继承,或是某些数据特性来说。这一节咱们放个大招,运用兵法来写代码,保证初学者看不懂,既便能看懂,也不知道为什么这样做,即便知道为什么这样做,没有系统学习过的人也做不好。   这部兵法就是–设计模式。 前期准备   各位乡绅,读这本书前,个人建议要对 继承 , 类 (虽然JS在ES6之前没有类,但是可以通过一些手段实现类), 构造函数 ,

不见浅诗的博客 623

【SCADA】KingSCADA将数据插入SQLServer的方法

1、创建数据库及数据表格;2、配置ODBC数据源。3、通过KingSCADA与数据库建立连接,将数据写入数据库对应表格。

做有价值的事,积累有价值的笔记! 4958

代码要写成别人看不懂的样子(十)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言状态模式 前言   各位写代码的时候,经常会出现条件判断吧,那么条件判断里面脸最熟的当属 if 了吧,这个东西在我们开始编码的时候,真的是隔一段时间不写,就浑身难受。   但是呢,if 这个东西,哪怕是再简单的判断,也会有隐含问题,而且在代码可读性上,条件判断的效果很不友好,当存在多重判断的时候,简直就是灾难。   所以为了解决条件判断的这些弊端,状态模式应运而生。 状态模式   状态模式:当一个对象的内部状态发生改变时,会导

不见浅诗的博客 447

选择的 Python 解释器无效,请尝试更改解释器以启用 IntelliSense、Lint 分析和调试等功能。请查看输出,详细了解解释器无效的原因。

摘要:在VS Code中配置Anaconda Python解释器时若出现"解释器无效"错误,可通过修改用户设置解决。具体步骤:1) 按Ctrl+Shift+P打开命令面板;2) 搜索并打开用户设置JSON文件;3) 添加conda路径配置项,示例格式为"python.condaPath": "D:\\Anaconda\\setup\\Scripts\\conda.exe";4) 同时启用环境激活选项"python.terminal.act

猿小白的博客 843

【嵌入式 – GD32开发实战指南(ARM版本)】第1部分 基础篇 - 第1章 开发环境搭建

开发环境: MDK:Keil 5.30 MCU:GD32F207IK 1.1 GD32F207I-EVAL开发板简介 笔者使用的开发板是兆易创新设计的GD32F207I-EVAL开发板。 GD32F207I-EVAL开发板使用 GD32F207IK作为主控制器,主频120MHz、集成3MB Flash、256KB SRAM、通用定时器*10、Adv. TM*2、Basic TM*2、系统时钟*1、看门狗*2、RTC*1、USART*4、UART*4、I2C*3、SPI*3、I2S*1、SDIO*1、CAN

不问归期的博客 9986

代码要写成别人看不懂的样子(二十)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言惰性模式 前言   各位接触过机器学习没有,没了解过也没关系,这东西的大体思路就是,当第一次执行某种情况时,机器会去判断一些情况,到第二次执行的时候,就不需要再重复判断了,那么机器学习就会在第一次执行完成后,记录当时的计算过程,参数等数据,然后重新定义这种特定情况,当再次遇到后,不需要重复判断,直接获取上次的结果就行。   这个机器学习,就很像我们今天要说的惰性模式。真的超级像(我个人猜测,有可能当年发明机器学的人,就是惰性模式用的比较好

不见浅诗的博客 250

点云焊缝提取

本文介绍了一个基于PCL库的点云处理流程,包含三个核心模块:MLS平滑处理通过多项式拟合修正点云位置;差异提取通过双向匹配定位源/目标点云的非重叠区域;统计过滤剔除离群噪声点。该流程采用"平滑-筛选-净化"的通用思路,将复杂算法封装为可配置接口,实现了工业级点云预处理。文章重点分析了各模块的原理、PCL接口调用及参数设计逻辑,同时指出参数调优、算法扩展等深入探索方向,展现了PCL在点云处理中的模块化优势与实用价值。

weixin_45196569的博客 250

代码要写成别人看不懂的样子(三)

文章目录前言 前言   书接上回,我们学习了装饰器模式,不知各位道友是否还有印象,               

不见浅诗的博客 416

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

代码要写成别人看不懂的样子(八)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言注意事项 前言   铁汁们,我又来了,上节的组合模式,各位乱了没?不慌哈,这一节我们一起学个更乱的,就不会觉得上一个乱了。   通过不同的组合我们可以拼出很多我们像要的东西,只有想不到的需求,没有实现不了的方案。 注意事项      组合模式刚上手有点乱,不过核心思想还是比较清晰明确的,把需求拆分成一个一个子类,让所有子类继承一个虚拟父类就可以了。之前问过一位高人,如何才能写好代码,前辈指点:“ 惟手熟尔 ”。设计模式初学的时候,一定要

不见浅诗的博客 920

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

代码要写成别人看不懂的样子(十七)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言数据访问对象模式 前言   各位作为一名前端开发,大家有没有遇到过前端存储,比如用户初次进入程序,会有一个个性化引导,一般来说这块功能是交给后台同事来做的,但是有时候需要放在前端,来保存是否第一次登陆的字段。   那我们在本地存储的时候呢,可能会遇到很多问题,每添加一组数据,担心会不会覆盖别人的数据等等,本节的设计模式,就介绍怎么合理前端存储。 数据访问对象模式   抽象和封装对数据源的访问与存储, DAO通过对数据源链接的管理方便对数据

不见浅诗的博客 341

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

代码要写成别人看不懂的样子(六)

文章目录前言一、代理模式 前言   由于现在网络的发展,访问量,需求量越来越高,很难再使用一台服务器解决所有请求了,这就需要设置专门功能的服务器,来处理专门的业务。比如一个大型应用中,地图功能需要配置一台地图服务器,实况功能需要配置一台媒体服务器,数据上传专门来一台服务器,数据库系统再来一台,管理这些服务器还需要一台。在一些高并发的地方,一台服务器处理不过来,要把请求分散到各个服务器上进行处理。   服务器越来越多,不可避免地要考虑一个问题,跨域请求,跨域本身是一种安全策略,为了网络安全,不能直接请求非本服

不见浅诗的博客 368

代码要写成别人看不懂的样子(十六)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言链模式 前言   大家一定用过 JQuery 吧,这东西的一大特性就是链式调用,获取到某个元素后,直接连续执行多个方法,贼帅,其实我们也可以做到。   本节开始,就给大家介绍一些技巧性的设计模式,平时能经常用到,类似语法糖一样,简单易懂,而且功能奇妙,不会像前面的设计模式那样长篇大论,肯定比前面容易接收,而且有趣。 链模式    通过对象方法中,将当前对象返回,实现对同一个对象多个方法的链式调用。   

不见浅诗的博客 192

代码要写成别人看不懂的样子(十三)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言备忘录模式 前言   各位有没有做过分页,做分页一定会涉及到上一页,下一页,我们为了页面的流畅性,一般都是只请求当前页的数据,当点击上下页按钮的时候,才会请求对应的数据。   这个策略没错,但是用户一般都很调皮,不会老老实实,只点下一页,或者只点上一页,有时候可能会来回,上一页,下一页疯狂点击,那么这种情况就会疯狂请求数据。   页面很可能会卡死,那有没有什么方法能解决这种调皮鬼行为呢?   有时候我们可以增加点击限制,数据没返回之前,不

不见浅诗的博客 278

代码要写成别人看不懂的样子(五)

文章目录前言一、外观模式二、适配器模式 前言   通过前面几篇文章,大家估计对对象的创建有了一个新的认识,在很多大型应用里面,对象会相当复杂,但是其刚创建的时候,并不是这样,而是通过后续的组合,封装,才一步一步完善起来的,从本章节开始,我们一块来学一学,如何把这些对象组合的更合理,从而使想强大的功能。 一、外观模式   大家一定绑定过事件,而且一定像下面这样绑定过 document.onclick = fucntion(e) { e.preventDefault(); if(e.target !== d

不见浅诗的博客 455

代码要写成别人看不懂的样子(九)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言模板方法模式 前言   前几节的结构型设计模式,各位学的乱不乱,我个人刚开始接触的时候,也觉得很抽象,不太好理解,尤其是实战的时候,总是不知道在什么情况下使用。记住一点,当我们单纯的创建一个    模板方法模式       ...

不见浅诗的博客 397

代码要写成别人看不懂的样子(十九)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言简单模板模式 前言   大家有没有遇到过操作大量节点的情况,比如我们在页面上想要创建一个展示区域,这块区域,需要跟不同的选项来展示不同结构的内容,那我们就需要根据选项来操作不同的节点。首先创建节点,然后创建节点内容,将节点内容插入到创建的节点中,最后将节点插入到父节点中。   这一套操作下俩,一个节点就需要 4 步,如果节点比较多,那这性能消耗就有点遭不住了。   为了解决这一个问题,我们可以使用简单模板方法。如果各位接触过模板字符串

不见浅诗的博客 353

代码要写成别人看不懂的样子(十一)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言状态模式 前言    状态模式   

不见浅诗的博客 407

代码要写成别人看不懂的样子(四)

文章目录前言一、简单工厂模式二、安全工厂模式三、抽象工厂模式如何使用四、建造者模式 前言   书接上回,我们学习了装饰器模式,不知各位道友是否还有印象,本集,我们来学一学工厂相关的设计模式,分为三部,简单工厂,工厂方法和抽象工厂。   先个大家打个预防针,工厂相关的设计模式,都是需要面向对象来实现的,而面向对象只是一种思想上的转变,平时我们实现某个功能,是想着如何操作Dom,现在我们需要考虑,把我们要实现的东西转化成一个活生生的对象。   比如在页面左侧增加一个固定窗口展示广告,平常我们会写一个div,然后

不见浅诗的博客 273

代码要写成别人看不懂的样子(十二)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言访问者模式 前言    访问者模式    针对对象结构中的元素,定义在不改变对象的前提下访问结构中元素的新方法 。                         ...

不见浅诗的博客 253

代码要写成别人看不懂的样子(十八)

本篇文章参考书籍《JavaScript设计模式》–张容铭 文章目录前言节流模式 前言   今年3月份的时候,写过几篇文章,,介绍了一下浏览器的回流,重绘,以及对应的解决办法分别是节流和防抖。当时刚开始写博客,还很青涩,各位要是不嫌弃,可以简单扫一眼,链接在下面。 react中的防抖和节流,大佬封装的方法用起来就是爽–我们一起读源码 JavaScript防抖和节流–造轮子它不香吗 浏览器的小秘密–回流和重绘   今天我们一块研究的设计模式,就跟节流有关,这个东西平时不常用,但是一旦遇到相关问题后,不用还不

不见浅诗的博客 206
上一篇: 代码要写成别人看不懂的样子(六)
下一篇: 代码要写成别人看不懂的样子(八)
不见浅诗~
博客等级 码龄7年 506粉丝 129原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值