想要在JavaScript中应该面向对象的设计模式,首先就需要JavaScript支持某些面向对象的语言特性,比如说继承,封装,多态等等。至于这些语言特性所带来的好处,这里就不多说了。如果你并不打算使用JavaScript设计非常复杂的应用,你也应该对这些东西有所了解,至少它可以帮助你把代码写的更简洁,同时它也提供了一些写JavaScript代码的新思路。
为何要模拟接口?(Interface)
接口(Interface)是面向对象语言中很重要的一个概念,它为协作的开发人员提供了一个统一的开发协议,“面向接口编程而不是面向实现编程”是每个OO程序员都必须要知道的基本准则。同时,也有很多设计模式是基于Interface来实现的:
1. 工厂模式(factory pattern)
工厂对象负责替程序动态的产生某一类对象,这些产生的对象通常都继承于同一接口。
2. 组件模式(composite pattern)
如果没有接口,你基本上无法实现组件模式(抽象类好像可以)。
3.装饰器模式(decorator pattern)
装饰器模式为已有的对象提供了一种无需修改就能增加新的功能的方法。我们采用接口来定义装饰类所需提供的新功能。
4. 命令模式(command pattern)
通过接口我们定义出每个command类所必须要提供的方法。
如果模拟接口?
定义一个接口对象,并提供方法检测某个对象是否完全实现了该接口的方法:
当使用时, 先new一个Interface对象:
这个Interface对象中,定义了DynamicMap这个接口所有的方法声明。
然后对于应该继承该接口的对象,检测它是否真实的定义了所有方法:
为何要模拟接口?(Interface)
接口(Interface)是面向对象语言中很重要的一个概念,它为协作的开发人员提供了一个统一的开发协议,“面向接口编程而不是面向实现编程”是每个OO程序员都必须要知道的基本准则。同时,也有很多设计模式是基于Interface来实现的:
1. 工厂模式(factory pattern)
工厂对象负责替程序动态的产生某一类对象,这些产生的对象通常都继承于同一接口。
2. 组件模式(composite pattern)
如果没有接口,你基本上无法实现组件模式(抽象类好像可以)。
3.装饰器模式(decorator pattern)
装饰器模式为已有的对象提供了一种无需修改就能增加新的功能的方法。我们采用接口来定义装饰类所需提供的新功能。
4. 命令模式(command pattern)
通过接口我们定义出每个command类所必须要提供的方法。
如果模拟接口?
定义一个接口对象,并提供方法检测某个对象是否完全实现了该接口的方法:
/**
* Constructor
* How to use Interface:
* var MyWork = new Interface("MyWork", ["getName", "getValue"]);
* Interface.ensureImplements(results, MyWork);
*
* @param name
* @param methods
* @returns
*/
var Interface = function(name, methods) {
if (arguments.length != 2) {
throw new Error("Interface constructor called with " + arguments.length
+ "arguments, but expected exactly 2.");
}
this.name = name;
this.methods = [];
for ( var i = 0, len = methods.length; i < len; 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]);
}
};
/**
* If the object valid for interfaces.
* @param object
* @param interfaces...
*/
Interface.ensureImplements = function(object) {
if (arguments.length < 2) {
throw new Error("Function Interface.ensureImplements called with "
+ arguments.length + "arguments, but expected at least 2.");
}
for ( var i = 1, len = arguments.length; i < len; 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.");
}
}
}
};
当使用时, 先new一个Interface对象:
var DynamicMap = new Interface('DynamicMap', ['centerOnPoint', 'zoom', 'draw']);
这个Interface对象中,定义了DynamicMap这个接口所有的方法声明。
然后对于应该继承该接口的对象,检测它是否真实的定义了所有方法:
function displayRoute(mapInstance) {
Interface.ensureImplements(mapInstace, DynamicMap);
mapInstance.centerOnPoint(12, 34);
mapInstance.zoom(5);
mapInstance.draw();
...
}