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

程序员都看不懂的代码 <div class="J_TWidget" data-widget-config="{'effect': 'fade', 'circular': true ,'navCls':'toseise','activeTriggerCls':'odslos','contentCls':'piaofu'}" data-widget-type="Tabs"> <div class="piaofu" style="height: 480px"> <div class... 阅读详情

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

前言

  各位写代码的时候,经常会出现条件判断吧,那么条件判断里面脸最熟的当属 if 了吧,这个东西在我们开始编码的时候,真的是隔一段时间不写,就浑身难受。

  但是呢,if 这个东西,哪怕是再简单的判断,也会有隐含问题,而且在代码可读性上,条件判断的效果很不友好,当存在多重判断的时候,简直就是灾难。

  所以为了解决条件判断的这些弊端,状态模式应运而生。

状态模式

  状态模式:当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来像是改变了对象。

  我们可以将不同的状态结果封装在状态对象内部,然后该状态对象返回一个可被调用的接口方法,用于调用状态对下内部某种方法。做法如下:

//状态对象
var ResultState = function() {
	//结果保存在内部状态中
	var States = {
		//每种状态作为一种独立方法保存
		state0:funciton() {
			//处理结果0
			console.log('这是第一种情况');
		},
		state1:funciton() {
			//处理结果1
			console.log('这是第二种情况');
		},
		state2:funciton() {
			//处理结果2
			console.log('这是第三种情况');
		},
		state3:funciton() {
			//处理结果3
			console.log('这是第四种情况');
		},
	}
	//获取某一种状态,并执行其方法
	function show(result) {
		States['state' + result] && States['state' + result]();
	}
	return {
		//返回调用状态方法接口
		show: show
	}
} ();

  当我们想调用第三种结果的时候,我们就可以按照下面这种方法实现。

//展示结果3
ResultState.show(3);

  上面方法展示了状态模式的基本雏形,该模式主要目的就是将条件判断的不同结果转化为状态对象的内部状态。由于是内部状态,所以创建时设置成私有变量,只提供一个接口给外部进行增删改查,方便了我们对状态对象中,内部对象的管理。

  大家小时候都玩过超级玛丽吧,我们操作人物的时候可以跳跃,奔跑,蹲下,丢飞镖等,这些都是一个一个的状态,如果我们用 if 或者 switch 条件判断的话,那么后期会相当难维护,因为增加或者删除一个状态需要修改的地方太多了,这时使用状态模式帮我们管理就再合适不过了。

  对于超级玛丽,有的时候需要跳起来丢飞镖,有的时候需要蹲下丢飞镖,有的时候需要跑起来丢,这些组合状态如果用 if 或者 switch 判断的话,无形当中增加的成本是无法想象的。例如:

//单动作条件判断 每增加一个动作就需要添加一个判断
var lastAction = '';
function changeMarry(action) {
	if(action = 'jump') {
		//跳跃动作
	} else if(action = 'move') {
		//移动动作
	} else {
		//默认情况
	}
	lastAction = action;
}
//符合动作对条件判断的开销是翻倍的
var lastAction1 = '';
var lastAction2 = '';
function changeMarry(action1, action2) {
	if(action1 = 'throw') {
		//丢飞镖
	} else if(action1 = 'jump') {
		//跳跃
	} else if(action1 = 'jump' && action2 = 'throw') {
		//跳起来扔飞镖
	} else if(action1 = 'move' && action2 = 'throw') {
		//移动中扔飞镖
	}
	//保留上一个动作
	lastAction1 = action1 || '';
	lastAction2 = action2 || '';
}

  上面代码的可维护性和可读性都是很差的,日后对于新动作的添加或者修改原有动作的成本都是很大的。那么为了解决这一问题我们引入状态模式。解决思路如下:

  1.创建一个状态对象。

  2.内部保存状态变量。

  3.内部封装好每种动作对应的状态。

  4.状态对象返回一个接口对象,可以对内部状态进行修改或者调用。

//创建超级玛丽状态类
var MarryState = function() {
	//内部状态私有变量
	var _currentState = {},
		//动作与状态方法映射
		states = {
			jump: function() {
				//跳跃
				console.log('jump');
			},
			move: function() {
				//移动
				console.log('move');
			},
			throw: function() {
				//丢飞镖
				console.log('throw');
			},
			squat: function() {
				//蹲下
				console.log('squat');
			}
		};
	//动作控制类
	var Action = {
		//改变状态方法
		changeState: function() {
			//组合动作通过传递多个参数实现
			var arg = arguments;
			//重置内部状态
			_currentState = {};
			//如果有动作则添加动作
			if(arg.length) {
				//遍历动作
				for(var i = 0; len = arg.length; i < len; i++) {
					//向内部状态中添加动作
					_currentState[arg[i]] = true;
				}
			}
			//返回动作控制类
			return this;
		},
		//执行动作
		goes: function() {
			console.log('触发一次动作');
			//遍历内部状态保存的动作
			for(var i in currentState) {
				//如果该动作存在则执行
				states[i] && states[i]();
			}
			return this;
		}
	}
	//返回接口方法change ,goes
	return {
		change: Action.changeState,
		goes: Action.goes
	}
}

  超级玛丽的状态创建完成了,接下来就是使用了。

//创建一个超级玛丽
var marry = new MarryState();
marry
	.change('jump', 'throw')  //添加跳跃与丢飞镖动作
	.goes()          //执行动作
	.goes()          //执行动作
	.change('throw') //添加丢飞镖动作
	.goes();         //执行动作

  输出结果如下:

//触发一次动作
//jump
//throw
//触发一次动作
//jump
//throw
//触发一次动作
//throw

  改变状态类一个状态,就改变了状态对象的执行结果,是不是有点类似对象,让这些状态管理一下清晰了起来。

策略模式

  各位最近刚过完双十一吧,参与了将近五千亿的项目,感觉怎么样?凑满减的时候是不是感觉自己的数学水平又重新到达巅峰了。双十一活动有很多哈,比如满300减40,满200减25等等,有的商品不参与满减活动,但是可以先付定金,然后再付尾款,这一点像不像上面的刚介绍的状态模式,会用到很多条件判断。

  但是,情况又不太一样,不管商品采用哪种方案,一般都会只选取其中一种,比如该商品满300减40了,就不参与满200减25的活动了,如果使用状态模式的话,那就会为每一种商品,创建一个状态对象,这样做就会产生代码冗余。

  这个时候就需要用策略模式来解决当前问题了。策略模式结构上与状态模式很像,都是再内部封装一个对象,然后返回的接口对象实现对内部对象的调用。

  不同点是,策略模式不需要管理状态,状态间没有依赖关系,策略之间可以相互替换,在策略对象内部保存的是相互独立的一些算法。

//价格策略对象
var PriceStrategy = function() {
	//内部算法对象
	var strategy= {
		//满300减40
		reduce40: function(price) {
			return +price - ~~(price / 300) * 40; //~~表示parseInt
		},
		//满200减25
		reduce25: function(price) {
			return +price - ~~(price / 200) * 25;
		},
		//定金50付尾款
		deposit: function(price) {
			return +price - 50;
		},
	}
	//策略算法调用接口
	return function(algorithm, price) {
		//如果算法存在则调用算法,否则返回false
		return strategy[algorithm] && strategy[algorithm](price)
	}
} ();

  策略对象已经写出来了,我们可以看看怎么获取。

var price = PriceStrategy('reduce40', 1000);
console.log(price);    // 880

  策略模式其实应用的场景很多,比如 JQuery 动画中的缓冲函数,验证表单时候的正则算法。

//表单正则策略对象
var InputStrategy = function() {
	var strategy = {
		//是否为空
		notNull: funetion(value) {
			return /\s+/.test(value) ? '请输入内容' : '';
		},
		//是否是一个数字
		number: funetion(value) {
			return /^[0-9]+(\.[0-9]+)?$/.test(value) ? '' : '请输入数字';
		},
	}
	return {
		//验证接口 type 算法 value 表单值
		check: function(type, value) {
			//去除收尾空白符
			value = value.replace(/^\s+|\s+$/g, '');
			return strategy[type] ? strategy[type](value) : '没有该类型检测方法';
		},
		addStrategy: function(type, fn) {
			strategy[type] = fn;
		}
	}
} ();

  上面例子中,我们新增加了一个 addStrategy 用来增加新的策略,这个接口可以帮我们不用修改策略对象内部方法,便可以新增新的策略。用法如下:

//拓展可延续算法
InputStrategy.addStrategy('nickname', function(value) {
	return /^[a-zA-Z]\w{3,7}$/.test(value) ? '' : '请输入4-8位昵称, 如:LHXX';
});

  本片文章的两个设计模式还是很常见的,也比较简单,大家用一两次就能学会,使用后会给以后需求增加带来很多方便。




[知识图谱构建] 一.Neo4j图数据库安装初识及药材供应图谱实例 2012年5月,谷歌公司的知识图谱(Knowledge Graph)产品被正式提出,其旨在将人、地点、物等信息作为实体,将实体间的联系作为关系,并将实体和关系以图的形式进行存储。作为语义网的最新产物,知识图谱这种新型的搜索引擎改变了传统的文本搜索结果,而随后国内公司也开发出了相应产品,例如百度公司的“知心”和搜狗公司的“知立方”等。知识图谱本质上属于一种语义网。知识图谱中的每一条数据或事实一般会采用 &amp;lt;实体,属性,属性值&amp;gt; &amp;lt;实体, 关系, 阅读详情

相关推荐

麒麟系统grub被锁怎么办?双密码遗忘救援指南(实测V10 SP3版本)

本文详细介绍了麒麟系统V10 SP3版本在GRUB和root密码双遗忘情况下的救援指南。通过ISO镜像进入救援模式,结合单用户模式操作,实现密码重置与系统权限恢复,特别适用于等保合规环境。

384

如何写出同事看不懂的Java代码?

前几天,正巧赶上组里代码review,一下午下来,感觉整个人都血压拉满了。

1212

R语言实战:三因素方差分析(ANOVA)从入门到精通(附完整代码解析)

本文详细介绍了如何使用R语言进行三因素方差分析(ANOVA),从数据准备、模型构建到结果解读与可视化,提供完整代码解析。通过实战案例,帮助读者掌握复杂交互效应的分析方法,适用于科研、教育等多个领域的数据分析需求。

weixin_29081101的博客 244

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

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

不见浅诗的博客 1713

千兆以太网PHY设计:PCB原理图完整示例

深入解析千兆以太网PHY电路设计要点,提供完整的PCB原理图设计实例,帮助工程师掌握高速信号布局与电源去耦等关键技术,提升设计稳定性与信号完整性。

weixin_30633869的博客 628

告别GUI点点点:Formality形式化验证的TCL脚本自动化实战(附完整脚本)

本文详细介绍了如何通过TCL脚本实现Formality形式化验证的全流程自动化,显著提升验证效率并降低错误率。内容涵盖脚本框架解析、参数化设计、验证报告生成及团队协作策略,特别适合芯片设计工程师摆脱传统GUI操作,实现300%以上的效率提升。

weixin_33737134的博客 282

如何让别人看不懂你的 JS 代码?把你当大佬!

我们在上周的文章中一种奇特的 JavaScript 编码风格:Get 一种可以用来装逼的 JavaScript 编码风格,引起了广大网友的热议。这是实际上属于一种代码混淆技术,可以让们的代码更难阅读和逆向,同时也能租网一些恶意爬虫和自动化分析。天我就带大家来看看还有哪些其他能让 JavaScript 代码变得难以分析的代码混淆技术。通过一些转换,它可以变成下面这个样子:怎么做到的呢?我们一起来看一下~...

m0_62051288的博客 834

《Cesium 基础知识点》- 申请 Cesium Ion 密钥

一、访问 https://cesium.com/ion/signin/tokens 二、登录/注册 三、申请 四、使用 // 密钥 let defaultAccessToken = 'your token string'; // 设置 Cesium.Ion.defaultAccessToken = defaultAccessToken; // 初始化 let viewer = new Cesium.Viewer('cesiumContainer', {}); ...

前端技术 2570

【搞笑】如何写出别人看不懂自己也看不懂的代码

写在前面:   话说那是很久以前,代码交付按行收费,于是程序员们尽量写出更多行的代码。但自古以来就是道高一尺魔高一丈,于是兴起另一个职业---缩行师。缩行师的职责,就是去掉程序猿代码里多余的代码,将代码的行数尽量降到最低。剥削和反剥削的阶级斗争从来就没有停止过,直到代码交付不再以行数计费。   至于有兴趣了解缩行师职业的人,可以戳一下这里:缩行师职业简介   现如今,天下大势以定,...

dde2522的博客 606

软硬件融合加速技术系列文章

目录 文章目录目录计算机组成原理Linux 操作系统原理处理器进程管理内存管理I/O 系统文件系统网络协议栈资源管理设备管理GPUFPGASmartNIC/DPU 计算机组成原理 《计算机组成原理 — 冯诺依曼体系结构》 《计算机组成原理 — 基本硬件设备》 《计算机组成原理 — CPU 中央处理器》 《计算机组成原理 — 指令系统》 《计算机组成原理 — 总线系统》 《计算机组成原理 — 存储系统》 《计算机组成原理 — 输入输出系统 — 存储控制器接口类型》 《计算机组成原理 — 服务器》 《计算机组成

烟云的计算 6806

Python 爬虫实战:爬取微博热搜与用户评论数据

本文系统讲解微博热搜榜单与用户评论数据的爬取技术方案。针对微博热搜榜采用Requests+BeautifulSoup解析静态HTML结构,实现高效爬取;对于动态加载的评论数据,使用Selenium模拟浏览器行为规避反爬机制。详细阐述技术选型、反爬策略、数据清洗及存储方法,提供完整代码实现和输出示例。同时强调合规要求,提示开发者需在遵守平台规则的前提下进行数据采集。该方案为舆情分析和热点研究提供了可落地的技术实现路径。

2503_91057718的博客 1713

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

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

不见浅诗的博客 623

群晖如何安装软路由OpenWrt/iStoreOS作为旁路由(含网络设置、设置密码、还原出厂设置等linux命令ipk包)

openwrt的固件。

XiaoqiangClub的博客 7016

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

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

不见浅诗的博客 250

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

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

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

不见浅诗的博客 416

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

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

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

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

不见浅诗的博客 920

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

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

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

不见浅诗的博客 341

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

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

不见浅诗的博客 368

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

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

不见浅诗的博客 192

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

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

不见浅诗的博客 278

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

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

不见浅诗的博客 455

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

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

不见浅诗的博客 397

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

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

不见浅诗的博客 353

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

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

不见浅诗的博客 407

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

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

不见浅诗的博客 253

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

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

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值