• 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{ 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>
    

      

  • 相关阅读:
    Linux文件和目录
    Android/ios手机销售榜
    项目开发流程
    游戏签到系统测试点
    项目上线后出现问题,该如何解决?
    公交地铁出行测试点
    初学测试
    测试用例的优先级
    Django的MVT模式与MVC模式
    JWT安装配置
  • 原文地址:https://www.cnblogs.com/zhuyang/p/4321033.html
Copyright © 2020-2023  润新知