zoukankan      html  css  js  c++  java
  • javascript设计模式

    1. 单例模式(Singleton)
    2. 工厂模式(Factory)
    3. 桥接模式(Bridge)
    4. 组合模式(Composite)
    5. 门面模式(Facade)
    6. 适配器模式(Adapter)
    7. 装饰者模式(Decorator)
    8. 享元模式(Flyweight)
    9. 代理模式(Proxy)
    10. 观察者模式(Observer)
    11. 命令模式(Command)
    下面代码在ie6&ie6+&chrome測试通过,code地址:
    转载请注明出处:

    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{ 200px;height:150px;padding:10px;border: 1px solid green; float: left;margin-right: 5px;margin-bottom: 5px;}
    		.day{ 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%; 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; 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>




  • 相关阅读:
    什么是ETL?5分钟看完秒懂
    横向滚动 css
    解决echarts中横坐标值显示不全(自动隐藏)问题
    Echarts
    post 二进制流下载文件
    如何停止foreach
    日期格式 js
    cookie 属性
    HTML5 file对象和blob对象的互相转换
    前端图片压缩
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7045077.html
Copyright © 2011-2022 走看看