您的位置:首页 > Web前端 > JavaScript

javascript设计模式

2014-04-28 12:43 573 查看
单例模式(Singleton)

工厂模式(Factory)

桥接模式(Bridge)

组合模式(Composite)

门面模式(Facade)

适配器模式(Adapter)

装饰者模式(Decorator)

享元模式(Flyweight)

代理模式(Proxy)

观察者模式(Observer)

命令模式(Command)

以下代码在ie6&ie6+&chrome测试通过,code地址:
https://github.com/liuyanzhi08/javascript-design-pattern

转载请注明出处:
http://blog.csdn.net/nancle/article/details/24633191

1.单例模式(Singleton):
<html><head><title>Singleten-单例模式</title><meta charset="utf-8"></head>
<body>
<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在singleten模块
MyNamespace.singleten = (function(){
var appid =  'helloJs';
return {
getAppId:function(){
return appid;
}
};
})();
console.log(MyNamespace.singleten.getAppId());
</script>
</body>
</html>


2.工厂模式(Factory)
<html><head><title>Factory-工厂模式</title><meta charset="utf-8"></head>
<body>
<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在xhr模块 ,xhr其实就是一个工厂,生产函数是getXHR
MyNamespace.xhr = (function(){
return {
getXHR:function(){
methods = [
function(){ return new XMLHttpRequest(); },
function(){ return new ActiveXObject('Microsoft.XMLHTTP'); },
function(){ return new ActiveXObject('Msxml2.XMLHTTP'); }
]
for(var i = 0; i < methods.length; i++){
try{
methods[i]();
}catch(e){
continue;
}
this.getXHR = methods[i]();
return methods[i]();
}
}
}
})();

alert(MyNamespace.xhr.getXHR());
</script>
</body>
</html>


3.桥接模式(Bridge)
<html><head><title>Bridge-桥接模式</title><meta charset="utf-8"></head>
<body>
<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在request模块
MyNamespace.request = (function(){
function getXHR(){
methods = [
function(){ return new XMLHttpRequest(); },
function(){ return new ActiveXObject('Microsoft.XMLHTTP'); },
function(){ return new ActiveXObject('Msxml2.XMLHTTP'); }
]
for(var i = 0; i < methods.length; i++){
try{
methods[i]();
}catch(e){
continue;
}
this.getXHR = methods[i]();
return methods[i]();
}
}
function handleReadystate(xhr, callback){
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
if(callback){
callback(xhr.responseText);
}
}
}

}
return function(method, uri, postData, callback){
//此处运用了桥接模式
var xhr = getXHR();
xhr.open(method, uri, true);
handleReadystate(xhr, callback);
xhr.send(postData || null);
}
})();

MyNamespace.request('post', 'test.php', "name=test&pwd=test", function(data){
alert(data);
})
</script>
</body>
</html>


4.组合模式(Composite)
<html><head><title>Composite-组合模式</title><meta charset="utf-8"></head>
<body>
<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在form模块
MyNamespace.form = (function(){
function Form(id, method, action){
this.element = document.createElement('form');
this.element.id = id;
this.element.method = method;
this.element.action = action;
this.store = [];
}
Form.prototype = {
add: function(fieldset){
this.element.appendChild(fieldset.getDom());
this.store.push(fieldset);
},
getDom: function(){
return this.element;
}
}
function Field(id){
this.element = document.createElement('fieldset');
this.element.id = id;
this.store = [];
}
Field.prototype = {
add: function(input){
this.element.appendChild(input.getDom());
this.store.push(input);
},
getDom: function(){
return this.element;
}
}
function Input(id, type, label){
this.wrapper =  document.createElement('div');

var labelTextNode = document.createTextNode(label);
this.label = document.createElement('label');
this.label.appendChild(labelTextNode);
this.wrapper.appendChild(this.label);

this.element = document.createElement(type);
this.element.id = id;
this.wrapper.appendChild(this.element);
}
Input.prototype = {
getDom: function(){
return this.wrapper;
}
}
return{
Form:Form,
Field:Field,
Input:Input
}
})();
window.onload = function(){
var form = new MyNamespace.form.Form('myForm', 'post', 'test.php');
var fields = [
new MyNamespace.form.Field('field1'),
new MyNamespace.form.Field('field2'),
new MyNamespace.form.Field('field3')
];
var inputs = [
[
new MyNamespace.form.Input('input1', 'input', 'input1:'),
new MyNamespace.form.Input('input2', 'textarea', 'input2:'),
new MyNamespace.form.Input('input3', 'input', 'input3:')
],
[
new MyNamespace.form.Input('input4', 'textarea', 'input4:'),
new MyNamespace.form.Input('input5', 'input', 'input5:'),
new MyNamespace.form.Input('input6', 'input', 'input6:')
],
[
new MyNamespace.form.Input('input7', 'input', 'input7:'),
new MyNamespace.form.Input('input8', 'input', 'input8:'),
new MyNamespace.form.Input('input9', 'textarea', 'input9:')
]

]
for(var i = 0; i < fields.length; i++){
form.add(fields[i]);
for(var j = 0; j < inputs.length; j++){
fields[i].add(inputs[i][j]);
}
}

document.getElementsByTagName('body')[0].appendChild(form.getDom());
}

</script>
</body>
</html>


5.门面模式(Facade)
<html><head><title>Facade-门面模式</title><meta charset="utf-8"></head>
<body>
<p id="greeting">Hello js!</p>
<p id="greeting1">Hello js1!</p>

<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在even模块
MyNamespace.event = (function(){
return {
setStyle: function(ids, prop, value){
for(var i = 0; i < ids.length; i++){
document.getElementById(ids[i]).style[prop] = value;
}
},
setCss: function(ids, styles){
for(var prop in styles){
if(!styles.hasOwnProperty(prop)){
continue;
}else{
this.setStyle(ids, prop, styles[prop]);
}
}
}
}
})();

MyNamespace.event.setCss(['greeting', 'greeting1'], {
'color': 'red',
'background': 'green'
})
</script>
</body>
</html>


6.适配器模式(Adapter)
<html><head><title>Adapter-适配器模式</title><meta charset="utf-8"></head>
<body>
<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在sample模块
MyNamespace.sample = (function(){
return {
aFunctin: function(arg1, arg2, arg3){
alert(arg1);
alert(arg2);
alert(arg3);
},
adapter: function(obj){
var i = 0;
var args = [];
for(var prop in obj){
if(!obj.hasOwnProperty(prop)) continue;
args[i++] = obj[prop];
}
this.aFunctin(args[0], args[1], args[2]);
}
}
})();

// MyNamespace.sample.aFunctin('a', 'b', 'c');
MyNamespace.sample.adapter({
'arg1':'a',
'arg2':'b',
'arg3':'c'
})
</script>
</body>
</html>


7.装饰者模式(Decorator)
<html><head><title>Decorator-装饰者模式</title><meta charset="utf-8"></head>
<body>
<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在sample模块
MyNamespace.sample = (function(){
function buildDom(){}
buildDom.prototype = {
startBuilt: function(){
var body = document.getElementsByTagName('body')[0];
for(var i = 0; i < 100; i++){
var list = document.createElement('ul');
for(var j = 0; j < 100; j++){
var item = document.createElement('li');
var text = document.createTextNode('test');
item.appendChild(text);
list.appendChild(item);
}
body.appendChild(list);
}
}
}
function timeDetector(buildDom){
this.buildDom = buildDom;
this.startTime;
}
timeDetector.prototype = {
startRun: function(){
this.startTime = (new Date()).getTime();
},
stopRun: function(){
var runTime = (new Date()).getTime() - this.startTime;
console.log("running cost:" + runTime + 'ms');
},
startBuilt: function(){
this.startRun();
this.buildDom.startBuilt();
this.stopRun();
}
}
return {
buildDom: buildDom,
timeDetector: timeDetector
}
})()

window.onload = function(){
var buildDom = new MyNamespace.sample.buildDom();
var buildDom = new MyNamespace.sample.timeDetector(buildDom);
buildDom.startBuilt();
}
</script>
</body>
</html>


8.享元模式(Flyweight)
<html><head><title>Flyweight-享元模式</title><meta charset="utf-8"></head>
<body>
<style type="text/css">
.month{width: 200px;height:150px;padding:10px;border: 1px solid green; float: left;margin-right: 5px;margin-bottom: 5px;}
.day{width: 15px;border: 1px solid green;float: left;margin-right: 5px;margin-bottom: 5px;padding: 2px;text-align: center;}
</style>
<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在calendar模块
MyNamespace.calendar = (function(){
function Day(){}
Day.prototype = {
getDom: function(num){
var element = document.createElement('div');
element.className = 'day';
var text = document.createTextNode(num);
element.appendChild(text);
return element;
}
}
var flyWeightDay = new Day();
function Year(year, parent) {
this.element;
this.parent = parent;
this.isLeapYear = !(year%400) || (!(year%4) && (year%100));
this.months = [];
for(var i = 0; i < 12; i++){
this.months.push(new Month(i, this.isLeapYear));
}

this.buildDom();
}
Year.prototype = {
buildDom: function(parent){
this.element = document.createElement('div');
this.element.className = 'year';
for(var i = 0; i < this.months.length; i++){
var month = this.months[i];
month.buildDom();
this.element.appendChild(month.getDom());
}
this.parent.appendChild(this.element);
}

}
function Month(month, isLeapYear){
this.days = [];
this.element;
this.numDay;
switch(month){
case 0:
this.numDay = 31;
break;
case 1:
this.numDay = isLeapYear?29:28;
break;
case 2:
this.numDay = 31;
break;
case 3:
this.numDay = 30;
break;
case 4:
this.numDay = 31;
break;
case 5:
this.numDay = 30;
break;
case 6:
this.numDay = 31;
break;
case 7:
this.numDay = 31;
break;
case 8:
this.numDay = 30;
break;
case 9:
this.numDay = 31;
break;
case 10:
numDay = 30;
break;
case 11:
this.numDay = 31;
break;
}
}
Month.prototype = {
buildDom: function(){
this.element = document.createElement('div');
this.element.className = 'month';
for(var i = 0;  i < this.numDay; i++){
this.element.appendChild(flyWeightDay.getDom(i+1));
}
},
getDom: function(){
return this.element;
}
}

return {
Year:Year
}
})();

window.onload = function(){
var body = document.getElementsByTagName('body')[0];
new MyNamespace.calendar.Year(2004, body);
}

/******************************************************
* 非享元版:使用了几百个Day对象,占用内存很大
***************************************/

// var MyNamespace = window.MyNamespace || {};
// // 定义在calendar模块
// MyNamespace.calendar = (function(){
// 	function Year(year, parent) {
// 		this.element;
// 		this.parent = parent;
// 		this.isLeapYear = !(year%400) || (!(year%4) && (year%100));
// 		this.months = [];
// 		for(var i = 0; i < 12; i++){
// 			this.months.push(new Month(i, this.isLeapYear));
// 		}

// 		this.buildDom();
// 	}
// 	Year.prototype = {
// 		buildDom: function(parent){
// 			this.element = document.createElement('div');
// 			this.element.className = 'year';
// 			for(var i = 0; i < this.months.length; i++){
// 				var month = this.months[i];
// 				month.buildDom();
// 				this.element.appendChild(month.getDom());
// 			}
// 			this.parent.appendChild(this.element);
// 		}

// 	}
// 	function Month(month, isLeapYear){
// 		this.days = [];
// 		this.element;
// 		var numDay;
// 		switch(month){
// 			case 0:
// 				numDay = 31;
// 				break;
// 			case 1:
// 				numDay = isLeapYear?29:28;
// 				break;
// 			case 2:
// 				numDay = 31;
// 				break;
// 			case 3:
// 				numDay = 30;
// 				break;
// 			case 4:
// 				numDay = 31;
// 				break;
// 			case 5:
// 				numDay = 30;
// 				break;
// 			case 6:
// 				numDay = 31;
// 				break;
// 			case 7:
// 				numDay = 31;
// 				break;
// 			case 8:
// 				numDay = 30;
// 				break;
// 			case 9:
// 				numDay = 31;
// 				break;
// 			case 10:
// 				numDay = 30;
// 				break;
// 			case 11:
// 				numDay = 31;
// 				break;
// 		}
// 		for(var i = 1; i <= numDay; i++){
// 			this.days.push(new Day(i));
// 		}

// 	}
// 	Month.prototype = {
// 		buildDom: function(){
// 			this.element = document.createElement('div');
// 			this.element.className = 'month';
// 			for(var i = 0;  i < this.days.length; i++){
// 				var day = this.days[i];
// 				day.buildDom();
// 				this.element.appendChild(day.getDom());
// 			}
// 		},
// 		getDom: function(){
// 			return this.element;
// 		}
// 	}
// 	function Day(num){
// 		this.num = num;
// 		this.element;
// 	}
// 	Day.prototype = {
// 		buildDom: function(){
// 			this.element = document.createElement('div');
// 			this.element.className = 'day';
// 			var text = document.createTextNode(this.num);
// 			this.element.appendChild(text);
// 		},
// 		getDom: function(){
// 			return this.element;
// 		}
// 	}
// 	return {
// 		Year:Year
// 	}
// })();

// window.onload = function(){
// 	var body = document.getElementsByTagName('body')[0];
// 	new MyNamespace.calendar.Year(2004, body);
// }
</script>
</body>
</html>


9.代理模式(Proxy)
<html><head><title>Proxy-代理模式</title><meta charset="utf-8"></head>
<body>
<style type="text/css">
body{padding: :0;margin:0;overflow: hidden;font-family: "微软雅黑"}
#modal-dialog{border: 3px solid green;padding: 10px;}
#modal-close{position: absolute;top: -20px;right: -18px;cursor: pointer;border: 2px solid green;padding: 1px;border-radius:50% 50%;width: 15px;height: 15px;text-align: center;line-height: 12px;color: green;font-weight: bold;}
#modal-loading{text-align: center;}
</style>

<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在component模块
MyNamespace.component = (function(){
function Modal(option){
}
Modal.prototype = {
_addListener: function(){
var that = this;
window.onresize =  function(){
that._resizeMask();
that._repositionDialog();
}
this.closeBtn.onclick = function(){
that.mask.parentNode.removeChild(that.mask);
that.dialog.parentNode.removeChild(that.dialog);
}
},
_resizeMask: function(){
this.mask.style.width = '100%';
this.mask.style.height = document.body.clientHeight;
},
_repositionDialog: function(){
this.dialog.style.left = (document.body.clientWidth-this.dialog.offsetWidth)/2;
this.dialog.style.top = (document.body.clientHeight-this.dialog.offsetHeight)/3;
},
show: function(){
var body = document.getElementsByTagName('body')[0];
//mask
this.mask = document.createElement('div');
this.mask.id = 'modal-mask';
this.mask.style.position = 'absolute';
this.mask.style.left = 0;
this.mask.style.top = 0;
this.mask.style.background = '#000';
this.mask.style.opacity = '0.5';
this.mask.style.filter = 'alpha(opacity=50)';
this._resizeMask();
body.appendChild(this.mask);
//diaglog
this.dialog = document.createElement('div');
this.dialog.innerHTML = 'HELLO MODAL!';
this.dialog.id = 'modal-dialog';
this.dialog.style.position = 'absolute';
//close-button
this.closeBtn = document.createElement('div');
var closeText = document.createTextNode('x');
this.closeBtn.id = 'modal-close';
this.closeBtn.appendChild(closeText);
this.dialog.appendChild(this.closeBtn);

body.appendChild(this.dialog);
this._repositionDialog();

this._addListener();
}
}
function ModalProxy(){
this.interval = null;
this.modal = new Modal();
this._initialize();
}
ModalProxy.prototype = {
_removeLoading: function(){
this.mask.parentNode.removeChild(this.mask);
this.loading.parentNode.removeChild(this.loading);
},
_resizeMask: function(){
this.mask.style.width = '100%';
this.mask.style.height = document.body.clientHeight;
},
_repositionLoading: function(){
this.loading.style.left = (document.body.clientWidth-this.loading.offsetWidth)/2;
this.loading.style.top = (document.body.clientHeight-this.loading.offsetHeight)/3;
},
_initialize: function(){
var that = this;
var body = document.getElementsByTagName('body')[0];
//mask
this.mask = document.createElement('div');
this.mask.id = 'modal-loading-mask';
this.mask.style.position = 'absolute';
this.mask.style.left = 0;
this.mask.style.top = 0;
this.mask.style.background = '#000';
this.mask.style.opacity = '0.5';
this.mask.style.filter = 'alpha(opacity=50)';
this._resizeMask();
this.num = 0;
body.appendChild(this.mask);
//loading text
this.loading = document.createElement('div');
this.loading.innerHTML = 'loading...';
this.loading.id = 'modal-loading';
this.loading.style.position = 'absolute';

body.appendChild(this.loading);
this._repositionLoading();
window.onresize =  function(){
that._resizeMask();
that._repositionLoading();
}

this.interval = setTimeout(function(){
that._checkInitailization();
}, 100);
},
_checkInitailization: function(callback){
var that = this;
this.num++;
//这里用num++ 来模拟等待数据处理的过程. this.num > 20为loading停止条件
if(this.num > 20){
clearTimeout(this.interval);
this._removeLoading();
callback();
}else{
document.title =  this.num;
this.interval = setTimeout(function(){
that._checkInitailization(callback)
}, 100);
}
},
show: function(){
var that = this;
this._checkInitailization(function(){
that.modal.show();

});
}
}
return {
ModalProxy:ModalProxy
}
})();

window.onload = function(){
var mp = new MyNamespace.component.ModalProxy();

mp.show();

}
</script>

1. Singleton - 单例模式<br/>
2. Factory   - 工厂模式<br/>
3. Bridge    - 桥接模式<br/>
4. Composite - 组合模式<br/>
5. Facade	 - 门面模式<br/>
6. Adapter   - 适配器模式<br/>
7. Decorator - 装饰者模式<br/>
8. Flyweight - 享元模式<br/>
9. Proxy	 - 代理模式<br/>
</body>
</html>


10.观察者模式(Observer)
<html><head><title>Observer-观察者模式</title><meta charset="utf-8"></head>
<body>
<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在sample模块
MyNamespace.sample = (function(){
function Publisher(){
this.subscribers = [];
}
Publisher.prototype = {
publish: function(msg){
for(var i in this.subscribers){
this.subscribers[i].msg = msg;
}
alert('Publish:"'+msg+'"');
}
}
function Subscriber(name){
this.name = name;
this.msg;
}
Subscriber.prototype = {
subscribe: function(publisher){
for(var i in publisher.subscribers){
if(publisher.subscribers[i] == this){
return;
}
}
publisher.subscribers.push(this);
},
getMsg: function(){
alert(this.name + ' has receive:"' + this.msg + '"');
}
}
return {
Publisher:Publisher,
Subscriber:Subscriber
}
})();

var p = new MyNamespace.sample.Publisher();
var s1 = new MyNamespace.sample.Subscriber('s1');
var s2 = new MyNamespace.sample.Subscriber('s2');
var s3 = new MyNamespace.sample.Subscriber('s3');

s1.subscribe(p);
s2.subscribe(p);
s3.subscribe(p);

p.publish('new report');
s1.getMsg();
s2.getMsg();
s3.getMsg();

p.publish('another report')
s1.getMsg();
s2.getMsg();
s3.getMsg();

</script>
</body>
</html>


11.命令模式(Command)
<html><head><title>Command-命令模式</title><meta charset="utf-8"></head>
<body>
<style type="text/css">
.memu{}
.menu-item{padding: 5px 10px; background: green;width: 100px;cursor: pointer;margin-bottom: 1px;}
</style>
<script type="text/javascript">
var MyNamespace = window.MyNamespace || {};
// 定义在composite模块
MyNamespace.composite = (function(){
function Menu(parent){
this.parent = parent;
this.element = document.createElement('div');
this.element.className = 'menu';
this.parent.appendChild(this.element);
}
Menu.prototype = {
add: function(menuItem){
this.element.appendChild(menuItem.element);
}
}
function MenuItem(name, command){
this.element = document.createElement('div');
this.element.className = 'menu-item';
var itemName = document.createTextNode(name)
this.element.appendChild(itemName);
this.command = command;
this._addAction();
}
MenuItem.prototype = {
_addAction: function(){
var that = this;
this.element.onclick = function(){
that.command.run();
}
}
}
function Command(name){
this.name = name;
}
Command.prototype = {
run: function(){
alert(this.name);
}
}
return {
Menu: Menu,
MenuItem: MenuItem,
Command: Command
}
})();

window.onload = function(){
var body = document.getElementsByTagName('body')[0];
var menu = new MyNamespace.composite.Menu(body);
var editCommand = new MyNamespace.composite.Command('edit');
var saveCommand = new MyNamespace.composite.Command('save');
var menuItem = new MyNamespace.composite.MenuItem('选项一', editCommand);
var menuItem1 = new MyNamespace.composite.MenuItem('选项二', saveCommand);
menu.add(menuItem);
menu.add(menuItem1);
}

</script>
</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息