JavaScript设计模式读书笔记之一:接口
接口
在JavaScrip中模仿接口
用注释描述接口
/*
interface Composite {
function add(child);
function remove(child);
function getChild(index);
}
interface FormItem {
function save();
}
*/
var Composite = function(id, method, action) { // implements Composite, FormItem
};
Composite.prototype.add = function(child) {
console.log("add");
}
Composite.prototype.remove = function(child) {
console.log("remove");
}
Composite.prototype.getChild = function(index) {
console.log("getChild");
}
Composite.prototype.save = function() {
console.log("save");
};
var instance = new Composite(1, 2, 3);
instance.add();
instance.remove();
instance.getChild();
instance.save();
用属性检查模仿接口
概括:
- 一个方法用于表明自己实现了哪些接口。
- 一个方法用于验证是否实现了所有的接口,如果没有,则抛出异常。
- 一个方法用于判断某个类是否实现了所有的接口。
缺点:
- 自己说自己实现了什么接口,但是可能自己并没有实现,但是代码却不会抛出异常。
- 用了两层for循环,会引起性能消耗。
/*
interface Composite {
function add(child);
function remove(child);
function getChild(index);
}
interface FormItem {
function save();
}
*/
var CompositeForm = function(id, method, action) {
this.implementsInterface = ['Composite', 'FormItem'];
// ...
}
function addForm(instance) {
if(!implements(instance, 'Composite', 'FormItem')) {
throw new Error('Object does not implement a required interface');
}
if(!implements(instance, 'test', 'FormItem')) {
throw new Error('Object does not implement a required interface');
}
}
function implements(object) {
for(var i = 1;i < arguments.length;i++) {
var interfaceName = arguments[i];
var interfaceFound = false;
for(var j = 0;j < object.implementsInterface.length;j++) {
if(object.implementsInterface[j] == interfaceName) {
interfaceFound = true;
break;
}
}
if(!interfaceFound) {
return false;
}
}
return true;
}
var instance = new CompositeForm(1, 2, 3);
addForm(instance);
用鸭式辨型模仿接口
- 类是否声明自己支持哪些接口并不重要, 只要具有这些接口中的方法就可以了。
- 它把对象实现的方法集作为判断它是不是某个类的实例的唯一标准。
- 也就是说,如果对象具有与接口定义的方法同名的所有方法,那么就可以认为它实现了这个接口。
// Interface.js文件
/*
* 一个接口
* @param {string} name 接口的名字
* @param {array} methods 接口要实现的方法
* @class
*/
var Interface = function(name, methods) {
if(arguments.length !== 2) {
throw new Error("Interface constructor called with " + arguments.length
+ "arguments, but expectly exactly 2.");
}
this.name = name;
this.methods = [];
for(var i = 1;i < methods.length;i++) {
if(typeof methods[i] !== "string") {
throw new Error("Interface constructor expects method names to be "
+ "passed in as a string");
}
this.methods.push(methods[i]);
}
};
/*
* static class method 用于实现检测对象是否实现了接口里的所有方法
*
* @param {object} object 它应该包含一个对象的实例和至少一个接口
*
*/
Interface.prototype.ensureImplements = function(object) {
if(arguments.length < 2) {
throw new Error("Function Interface.ensureImplements called with " + arguments.length
+ "arguments, but expectly at least 2.");
}
for(var i = 1;i < arguments.length;i++) {
var interface = arguments[i];
if(interface.constructor !== Interface) {
throw new Error("Function interface.ensureImplements expects arguments "
+ "two and above to be instances of Interface.");
}
for(var j = 0, methodsLen = interface.methods.length;j < methodsLen;j++) {
var method = interface.methods[j];
if(!object[method] || typeof object[method] !== 'function') {
throw new Error("Function Interface.ensureImplements: Object "
+ "does not implement the " + interface.name
+ " interface.Method " + method + " was not found");
}
}
}
}
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="Interface.js"></script>
<script type="text/javascript">
// 实例化一个接口
var PeopleInterface = new Interface('PeopleInterface', ['run', 'eat']);
// 封装一个People类
var People = function(name) {
this.name = name;
};
People.prototype.run = function() {
console.log(this.name + " is running...");
};
People.prototype.eat = function() {
console.log(this.name + " is eating...");
};
// 实例化一个People对象
var yzf = new People('yzf');
function addPeople(instance) {
// 对yzf进行检测,看它是否完全继承了PeopleInterface接口
PeopleInterface.ensureImplements(yzf, PeopleInterface);
// 如果没有抛出异常,就可以使用下面这些方法了
yzf.run();
yzf.eat();
}
addPeople(yzf);
</script>
</body>
</html>
依赖于接口的设计模式
工厂模式
组合模式
装饰者模式
命令模式
JavaScript设计模式读书笔记之一:接口的更多相关文章
- JavaScript设计模式:读书笔记(未完)
该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...
- JavaScript设计模式 -- 读书笔记
JavaScript设计模式 一. 设计模式 一个模式就是一个可重用的方案: 有效的解决方法.易重用.善于表达该解决方案: 未通过"模式特性"测试的模式称为模式原型: 三规则:适用 ...
- 《你不知道的javascript》读书笔记2
概述 放假读完了<你不知道的javascript>上篇,学到了很多东西,记录下来,供以后开发时参考,相信对其他人也有用. 这篇笔记是这本书的下半部分,上半部分请见<你不知道的java ...
- HeadFirst设计模式读书笔记--目录
HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...
- 《编写可维护的javascript》读书笔记(中)——编程实践
上篇读书笔记系列之:<编写可维护的javascript>读书笔记(上) 上篇说的是编程风格,记录的都是最重要的点,不讲废话,写的比较简洁,而本篇将加入一些实例,因为那样比较容易说明问题. ...
- JavaScript设计模式学习笔记
1 JavaScript设计模式深入分析 私有属性和方法:函数有作用域,在函数内用var 关键字声明的变量在外部无法访问,私有属性和方法本质就是你希望在对象外部无法访问的变量. 特权属性和方法:创建属 ...
- Javascript & JQuery读书笔记
Hi All, 分享一下我学JS & JQuery的读书笔记: JS的3个不足:复杂的文档对象模型(DOM),不一致的浏览器的实现和便捷的开发,调试工具的缺乏. Jquery的选择器 a. 基 ...
- Head First 设计模式读书笔记(1)-策略模式
一.策略模式的定义 策略模式定义了算法族,分别封装起来,让它们之间可以互换替换,此模式让算法的变化独立使用算法的客户. 二.使用策略模式的一个例子 2.1引出问题 某公司做了一套模拟鸭子的游戏:该游戏 ...
- JavaScript设计模式系列学习笔记目录
说明 本系列笔记参考书籍<JavaScript设计模式>.<JavaScript高级程序设计3> 参考博客:汤姆大叔博客:http://www.cnblogs.com/TomX ...
随机推荐
- 纪中集训 Day 5
不知不觉已经day 5了啊 今天早上醒来,觉得要AK的节奏,结果就立flag了 - - 30分QAQ 其实第一题应该得想得到的,还有T2也能够解决的(话说后来看别人的代码写的好赞啊QAQ) 然后下午就 ...
- Angular2 Service实践——实现简单音乐播放服务
引言: 如果说组件系统(Component)是ng2应用的躯体,那把服务(Service)认为是流通于组件之间并为其带来生机的血液再合适不过了.组件间通信的其中一种优等选择就是使用服务,在ng1里就有 ...
- 阿里云LINUX服务器配置HTTPS(NGINX)
本文首发于:http://www.fengzheng.pub/archives/238.html 背景说明 服务器为阿里云 ECS,操作系统为 CentOS 6.5. 部署配置说明 第一步,安装ngi ...
- POJ 2396 Budget 有上下界的网络流
POJ 2396 Budget 题意简述:给定矩阵(每个元素都是非负整数)各行各列的和,并且限制其中的某些元素,给出一个可行解,特殊评测.矩阵规模小于200*20. 网络流的模型是显而易见的,不过对 ...
- css伪元素用法大全
本文主要讲解css伪元素的用法,有需要的朋友可以阅读此文.本文讲解的伪元素有:before,after. 什么是伪元素(Pseudo element)? 伪元素不是真正的元素,不存在与文档之中,所以j ...
- DOM树的增查改删总结
DOM树的增查改删总结 摘要:对HTML DOM的操作是前端JavaScript编程时必备的技能,本文是我自己对DOM树操作的总结,主要是方法的罗列,原理性的讲述较少,适合大家用于理清思路或是温习 一 ...
- C#泛型编程
1.泛型的概念 C#中的泛型与C++中的模板类似,泛型是实例化过程中提供的类型或类建立的.泛型并不限于类,还可以创建泛型接口.泛型方法,甚至泛型委托.这将极大提高代码的灵活性,正确使用泛型可以 ...
- Maven与Eclipse使用中遇到的问题解决之道
在使用Maven以及Eclipse的Maven插件时,我和同事遇到了一下几个问题,本着知其然知其所以然的学习精神,总结如下: Unrecognised tag 问题 由于我使用本地代理仓库,所以set ...
- 你真的了解volatile吗,关于volatile的那些事
很早就接触了volatile,但是并没有特别深入的去研究她,只有一个朦胧的概念,就是觉得 用她来解决可见性的,但可见性又是什么呢? 最近经过查阅各种资料,并结合自己的思考和实践,对volatile有了 ...
- 大数据系列之Flume+HDFS
本文将介绍Flume(Spooling Directory Source) + HDFS,关于Flume 中几种Source详见文章 http://www.cnblogs.com/cnmenglang ...