<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>javascript高级语法14-组合模式实现</title>
</head>
<body>
<script>
//接口
var Interface = function(name,methods){
if(arguments.length != 2){
alert("interface must have two paramters...");
}
this.name = name;//这个是接口的名字
this.methods = [];//定义个空数组来转载函数名
for (var i = 0; i < methods.length; i++) {
if(typeof methods[i] != "string"){
alert("method name must is String ...")
}else{
this.methods.push(methods[i])
}
}
}
//定义接口的一个静态方法来实现接口与实现类的直接检验
//静态方法不要写成Interface.prototype.* 因为这是写到接口原型连上的
//我们要把静态的函数直接写到类层次上
Interface.ensureImplements = function(object){
if(arguments.length<2){
alert("必须最少是2个参数");
return false;
}
//遍历
for (var i = 1; i < arguments.length; i++) {
var inter = arguments[i];
//如果你是接口就必须是Interface类型的
if(inter.constructor != Interface){
throw new Error("if is interface class must is Interface type");
}
//遍历函数集合并分析
for (var j = 0; j < inter.methods.length; j++) {
var method = inter.methods[j];
//实现类中必须有方法名字 和 接口中所有的方法名项目
if(!object[method] || typeof object[method] != "function"){
throw new Error("实现类并没有完全实现接口中的所有方法...");
}
}
}
} /*
* 组合模式
*/ function demo(){
var composite = new Interface("composite",["getChildByName","add"]);
var student = new Interface("composite",["goToClass","finishClass"]);
//定义组合类
var compositeObj = function(name){
this.name = name;
this.type = "com"; //默认是组合类
var childs = new Array();
//得到相关的所有孩子节点
this.getChildByName=function(name){
//涉及到递归
var toChilds = new Array();
if(!name){
for(var i=0;i<childs.length;i++){
if(childs[i].type == "com"){ //组合节点
toChilds = toChilds.concat(childs[i].getChildByName());
}else{ //叶子节点
toChilds.push(childs[i]); }
}
}else{
for(var i=0;i<childs.length;i++){
if(childs[i].name == name){
if(childs[i].type == "com"){
toChilds = toChilds.concat(childs[i].getChildByName());
break;
}else{
toChilds.push(childs[i]);
break;
}
}else{
if(childs[i].type == "com"){
toChilds = toChilds.concat(childs[i].getChildByName(name));
}
}
}
}
return toChilds;
}
//增加子节点
this.add = function(child){
childs.push(child);
return this;
}
//上课
this.goToClass = function(name){
var toChilds = this.getChildByName(name);
for(var i=0;i<toChilds.length;i++){
toChilds[i].goToClass(); //子类的GoToClass方法
}
}
//下课
this.finishClass = function(name){
var toChilds = this.getChildByName(name);
for(var i=0;i<toChilds.length;i++){
toChilds[i].finishClass(); //子类的GoToClass方法
}
}
//接口验证
Interface.ensureImplements(this,composite,student);
}
//定义叶子类
var studentObj = function(name){
this.name = name;
this.type = "stu";//默认是叶子 //得到相关的所有孩子节点
this.getChildByName=function(name){
if(this.name == name){
return this;
}else{
return null;
}
}
//增加子节点
this.add = function(child){
throw new Error("add 不能被初始化在叶子类中!");
}
//上课
this.goToClass = function(name){
document.write(this.name + "去上课<br>")
}
//下课
this.finishClass = function(name){
document.write(this.name + " 下课<br>")
}
Interface.ensureImplements(this,composite,student);
} //测试;
var a = new studentObj("a");
var b = new studentObj("b");
var c = new studentObj("c");
var d = new studentObj("d");
var e = new studentObj("e");
var f = new studentObj("f");
var g = new studentObj("g");
var h = new studentObj("h");
var one = new compositeObj("一班");
var oneOne = new compositeObj("一班一组");
oneOne.add(a).add(b);
var oneTwo = new compositeObj("一班二组");
oneTwo.add(c).add(d);
one.add(oneOne).add(oneTwo);
var two = new compositeObj("二班");
var twoOne = new compositeObj("二班一组");
twoOne.add(e).add(f);
var twoTwo = new compositeObj("二班二组");
twoTwo.add(g).add(h);
two.add(twoOne).add(twoTwo);
var xuexiao = new compositeObj("新学校");
xuexiao.add(one).add(two); //客户端调用API
xuexiao.goToClass();
document.write("------------------------<br>");
xuexiao.goToClass("一班");
document.write("------------------------<br>");
xuexiao.goToClass("二班一组");
document.write("------------------------<br>");
xuexiao.goToClass("a"); }
demo();
</script>
</body>
</html>