java Script 組合模式 簡單例項
阿新 • • 發佈:2019-02-20
(function() {
Array.prototype.each = function(fn) {
try {
this.i || (this.i = 0);
if(this.length > 0 && fn.constructor == Function) {
while(this.i < this.length) {
var e = this[this.i];
if(e && e.constructor == Array) {
e.each(fn);
} else {
fn.apply(e, [e]);
}
this.i++
}
this .i = null;
}
} catch(ex) {
}
return this
}
var Interface = function(name, methods) {
//1.判斷實參的個數
if(arguments.length != 2) {
throw new Error("引數不夠");
}
this .name = name;
this.methods = [];
for(var i = 0, len = methods.length; i < len; i++) {
if(typeof methods[i] !== "string") {
throw new Error("方法名必須是String型別");
}
this.methods.push(methods[i]);
}
}
Interface.ensureImplements = function(object) {
if(arguments.length < 2) {
throw new Error("引數個數不夠")
}
for(var i = 1, len = arguments.length; i < len; i++) {
var interfaceName = arguments[i];
if(interfaceName.constructor !== Interface) {
throw new Error("介面型別不匹配");
}
for(var j = 0; j < interfaceName.methods.length; j++) {
var methodName = interfaceName.methods[j];
if(!object[methodName] || typeof object[methodName] !== "function") {
throw new Error("方法不存在");
}
}
}
}
window.Interface = Interface;
})();
(function() {
var Org = function(name) {
this.name = name;
this.depts = [];
}
Org.prototype = {
constructor: Org,
addDepts: function(childDept) {
this.depts.push(childDept);
return this;
},
getDepts: function() {
return this.depts;
}
}
var Dept = function(name) {
this.name = name;
this.persons = [];
}
Dept.prototype = {
constructor: Org,
addPersons: function(childPersons) {
this.persons.push(childPersons);
return this;
},
getPersons: function() {
return this.persons;
}
}
var Person = function(name) {
this.name = name;
}
Person.prototype = {
constructor: Person,
work: function() {
console.info("努力工作的" + this.name);
},
sleep: function() {
console.info("睡覺中的" + this.name);
}
}
var a = new Person("a");
var b = new Person("b");
var c = new Person("c");
var d = new Person("d");
var e = new Person("e");
var f = new Person("f");
var A = new Dept("A");
A.addPersons(a).addPersons(b).addPersons(c);
var B = new Dept("B");
B.addPersons(d).addPersons(e).addPersons(f);
var Aa = new Org("Org");
Aa.addDepts(A).addDepts(B);
//最終的節點落實在人上面 如果是部門呢?如果部門下面 又建立了部門呢? OMG 不敢想了,此時 組合模式就誕生了。
for(var i = 0, depts = Aa.getDepts(); i < depts.length; i++) {
for(var j = 0, persons = depts[i].getPersons(); j < persons.length; j++) {
if(persons[j]["name"] === "e") {
//persons[j].work();
}
}
}
})();
(function() {
/*
* 應用場景(節點隨便新增完全無視)
總公司--->上海分公司--->財務部門--->財務A
* --->財務B
* --->銷售部門--->銷售A
* --->銷售B
* --->財務部門--->財務A
* --->財務B
--->銷售部門 --->銷售A
*/
var CompositeInterface = new Interface("CompositeInterface", ["addChild", "getChild"]);
var LeafInterface = new Interface("LeafInterface", ["work", "sleep"]);
//組合物件
var Composite = function(name) {
this.name = name;
this.type = "Composite";
this.children = [];
};
Composite.prototype = {
constructor: Composite,
addChild: function(child) {
this.children.push(child);
return this;
},
getChild: function(name) {
var elements = [];
var pushLeaf = function(item) {
if(item.type === "Composite") {
item.children.each(arguments.callee);
} else if(item.type === "Leaf") {
elements.push(item);
}
}
if(name && this.name !== name) {
this.children.each(function(item) {
if(item.name === name && item.type === "Composite") {
item.children.each(pushLeaf);
}
if(item !== name && item.type === "Composite") {
item.children.each(arguments.callee);
}
if(item.name === name && item.type === "Leaf") {
elements.push(item);
}
});
} else {
this.children.each(pushLeaf);
}
return elements;
},
work: function(name) {
var childObjects = this.getChild(name);
for(var i = 0; i < childObjects.length; i++) {
childObjects[i].work();
}
},
sleep: function(name) {
var childObjects = this.getChild(name);
for(var i = 0; i < childObjects.length; i++) {
childObjects[i].sleep();
}
}
}
//葉子物件
var Leaf = function(name) {
this.name = name;
this.type = "Leaf";
};
Leaf.prototype = {
constructor: Leaf,
addChild: function(child) {
throw new SyntaxError("最底層節點 無法在新增子節點");
},
getChild: function(name) {
if(this.name === name) {
return this;
}
return null;
},
work: function() {
console.info("努力工作的" + this.name);
},
sleep: function() {
console.info("睡覺中的" + this.name);
}
}
var a = new Leaf("a");
var b = new Leaf("b");
var c = new Leaf("c");
var d = new Leaf("d");
var e = new Leaf("e");
var f = new Leaf("f");
var A = new Composite("A");
A.addChild(a).addChild(b).addChild(c);
var B = new Composite("B");
B.addChild(d).addChild(e).addChild(f);
var Aa = new Composite("Org");
Aa.addChild(A).addChild(B);
/*呼叫規則*/
Aa.work();
Aa.work("A");
Aa.work("b");
})();