javascript设计模式

以下代码在ie6&ie6+&chrome测试通过,code地址:

https://code.csdn.net/liuyanzhi08/javascript_design_pattern/tree/master 

 

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>

  

你可能感兴趣的:(JavaScript)