js設計模式

基礎知識

變量,聲明,數據類型,
類型轉換javascript

/**
 * 基礎教程
 */
(function(){
    /**
     * 變量
     * 他是用於存儲信息的一個容易
     * 規則
     * 他是敏感大小寫的 (Y和y他是2個不一樣的變量)
     * 變量名字必須以字母或者下劃線開始 數字不能夠 $("#id")
     */
    x = 5;
    length = 66.15;
    // 你不用var
    var k = "YUNFENGCHENG";
    alert(k)
    k = "USPCAT.COM";
    //在javascript中 建立這個動做常常揮別稱之爲"聲明"
    //您能夠經過var 語句來聲明jS變量
    var x = "44";
    var carname;
    //注意的地方
    //若是變量再次被定義一會他的原始數值將不被持有
})()
/**
 * 數據類型和類型轉換
 */
(function(){
/**
 * 基本數據類型(3種)
 * (1)數字 number
 *   例如 3.1415927 ,0.251,.2,100,1.478E
 * (2)字符串
 *   string
 * (3)布爾 booble
 */
 //數字型轉字符串
 var num1 = 3.1415927;
 var str1 = Number.toString(num1); 
 document.write(typeof str1 == "string");//true
 document.write("<br>")
 //四捨五入
 var num2 = num1.toFixed(2);
 document.write(num2);
 document.write("<br>")
 //返回指定的爲數的數字
 var num3 = num1.toPrecision(4);
 document.write(num3);
 document.write("<br>")
 //(Math) 介紹一點方法
 //四捨五入round
 document.write(Math.round(4.7));
 document.write("<br>")
 //隨機出處理0~1
 document.write(Math.random());
 document.write("<br>")
 //0~10的隨機數
 document.write(Math.floor((Math.random()*11)));
 document.write("<br>")
 document.write("-------------------------------<br>")
 
 //字符串
 //注意(轉義) pca't  要輸入 pca\'t \n 換行 
 /**
    \' \" \& 和好+ \\ \n \r 回車 
    \t \b \f 換頁
  */
 //屬性 length indexof substring chartAt(整數)
 //如何轉成數字
 var str2 = "USPCAT.COM";
 var str3 = "3.14";
 var number = Number(str3);
 document.write(typeof number == "number");
 document.write("<br>")
 document.write((str2 - 0)+"<br>");//NaN 非數值
 document.write((str3 - 1)+"<br>");//若是是減法他回自動將字符串轉成數字
 document.write((str3 + 1)+"<br>");//加法會當成字符串的拼接操做
 //布爾類型(boolean)
 //true | false
 var s = "";
 var o = {};//true
 var l = [];//true
 var n = null;
 var f = false;
 var u = undefined;
 document.write("-------------------------------<br>")
 if(!s){
     document.write("s is false<br>")
 }
 if(!o){
     document.write("o is false<br>")
 }
 if(!l){
     document.write("l is false<br>")
 }
 if(!n){
     document.write("n is false<br>")
 } 
 if(!f){
     document.write("f is false<br>")
 }
 if(!u){
     document.write("u is false<br>")
 }
 /**
s is false
f is false
u is false
n is false
  */
 if(str != "" && str != null && str != undefined){
     //...
 }
 if(str){
     //...
 }
 /**
  * 2複合類型
  * (1)數組-->有序的集合(array):下標(index) 是從0開始的
  * 例子
  * var arr = new Array();
  * (2)特殊的對象-->函數(function)
  */
 /**
  * 特殊值
  * (1)null 不是有效的對象\數組\數組\字符串  他們爲空 
  * (2)undefined 他是表明沒有定義 和空不是一個概念
  * [沒有] 可是有容易 有一個盒子可是盒子裏賣沒有東西
  * undefined 連盒子也沒有
  */
 /**
  * 內置特殊對象
  * Data對象
  * Error錯誤對象
  * ReExp對象
  */
})()
/**
 * 數據類型和類型轉換
 */
(function(){
    /**
      * 2複合類型
      * (1)數組-->有序的集合(array):下標(index) 是從0開始的     
     */
    //屬性
    //constructor 返回對建立次對象的數組的函數引用
    //index 
    //input
    //*length
    //方法
//    *concat 合併數組
//    *join 把數組按照必定的各式進行串聯
//    *push 數組的追加
//    *pop 刪除數組返回的最後一個元素
    //sort toString shift 刪除而且返回數組的第一個元素
    var arr = new Array();
    arr.push(1);
    arr.push(55);
    arr.push(5);
    arr.push(3);
    arr.push(9);
    //alert(arr.length)
    var arr2 = [1,2,3,45,6,7,8];
    //alert(arr2.join(":"));
    //alert(arr.concat(arr2).toString())
    for (var i = 0; i < arr2.length; i++) {
        document.write(arr2[i]+"<br>");
    }
    //擴展array的方法
    Array.each = function(array,fn){
        for (var i = 0; i < array.length; i++) {
            fn(array[i])
        }
    }
    Array.each(arr2,function(v){
        document.write(v+"<br>");
    })
})()

高級類

繼承和聚合

接口

1.註解的方法
2.屬性檢驗法
3.鴨式變形法java

/**
 * 1.註釋方法
 * 最簡單,可是功能也是最弱的
 * 他利用inerface和implement"文字"
 * 把他們用註解的方式顯示的表現出來
 */
(function(){
    /**
     * 用註釋來定義一個接口
     * interface PersonDao(){
     *     function add(obj);
     *  function remove(obj);
     *  function find(id);
     * }
     */
    //咱們用註釋的方式來實現他
    /**
     * PersonDaoImpl implement interface
     */
    var PersonDaoImpl = function(){
        
    }
    PersonDaoImpl.prototype.add = function(obj){
        //..
    }
    PersonDaoImpl.prototype.remove = function(obj){
        //..
    }
    PersonDaoImpl.prototype.find = function(id){
        //..
    }
    /**
     * 千萬不要感受他是沒有任何意義的
     * 1.大型的項目靠得就是規範和標準
     * 2.這樣的寫法會交你的程序員在沒有寫實現以前有充分時間作代碼的設計和架構
     * 3.缺點:要認爲的遵照
     */
})()
/**
 * 屬性檢驗法
 */
(function(){
    /**
     * 用註釋來定義一個接口
     * interface PersonDao(){
     *     function add(obj);
     *  function remove(obj);
     *  function find(id);
     * }
     */
    //咱們用註釋的方式來實現他
    var PersonDaoImpl = function(){
        this.implementInterface = ["PersonDao"];        
    }
    PersonDaoImpl.prototype.add = function(obj){
        alert(obj)
        //..
    }
    PersonDaoImpl.prototype.remove = function(obj){
        //..
    }
    PersonDaoImpl.prototype.find = function(id){
        //..
    }    
    function addObj(obj){
        var PersonDao = new PersonDaoImpl();
        //開始檢查
        if(!impl(PersonDao,"PersonDao")){
            throw new Error("類PersonDaoImpl沒有實現接口PersonDao");
        }else{
            PersonDao.add(obj);
        }
    }
    addObj("USCAPT.COM");
    /**
     * 他接受的是一個不定參數
     */
    function impl(Object){
        //遍歷出入對象的屬性
        for(var i=1;i<arguments.length;i++){
            var interfaceName = arguments[i];
            var interfaceFound = false;
            for(var j=0;j<Object.implementInterface.length;j++){
                if(Object.implementInterface[j] == interfaceName){
                    interfaceFound = true;
                    break;
                }
            }
            if(!interfaceFound){
                return false;
            }
        }
        return true;
    }
    
    
    
})()
/**
 * 3.鴨式變形法
 * 這個方法來源於一個國外的老頭他有一個名言(jim)
 * "像鴨子同樣走路而且會嘎嘎叫的東西就是鴨子"
 * 換言之
 * 若是對象具備與接口定義的方法名字的同命全部方法 那麼我就認爲你就是實現本接口
 */
(function(){
    //定義一個接口類
    var Interface = function(name,methods){
        if(arguments.length != 2){
            alert("interface must have two paramters...");
        }
        this.name = name;//這個是接口的名字
        this.methods = [];//定義個空數組來轉載函數名
        for (var i = 0; i < methods.length; i++) {
            if(typeof methods[i] != "string"){
                alert("method name must is String ...")
            }else{
                this.methods.push(methods[i])
            }
        }
    }
    //定義接口的一個靜態方法來實現接口與實現類的直接檢驗
    //靜態方法不要寫成Interface.prototype.* 由於這是寫到接口原型連上的
    //咱們要把靜態的函數直接寫到類層次上
    Interface.ensureImplements = function(object){
        if(arguments.length<2){
            alert("必須最少是2個參數");
            return false;
        }
        //遍歷
        for (var i = 1; i < arguments.length; i++) {
            var inter = arguments[i];
            //若是你是接口就必須是Interface類型的
            if(inter.constructor != Interface){
                throw new Error("if is interface class must is Interface type");
            }
            //遍歷函數集合並分析
            for (var j = 0; j < inter.methods.length; j++) {
                var method = inter.methods[j];
                //實現類中必須有方法名字 和 接口中全部的方法名項目
                if(!object[method] || typeof object[method] != "function"){
                    throw new Error("實現類而且沒有徹底實現接口中的全部方法...");
                }
            }
        }
    }
    //應用
    //定義本身的接口
    var GridMananger = new Interface("GridMananger",["add","remove","list"]);
    var FormMananger = new Interface("FormMananger",["save"])
    
    function commManager(){
        //先實現方法
        this.add = function(){
            alert("ok")
        }
        this.remove = function(){}
        this.list = function(){}
        this.save = function(){}
        //檢驗
        Interface.ensureImplements(this,GridMananger,FormMananger)
    }
    var c = new commManager();
    c.add();
    /**
     * 接口的重要性
     * 1.大型項目提升代碼的靈活度
     * 2.鬆耦合
     * 3.在團隊開發的時候,有寫時候你在真正編碼以前就能夠寫API(本身的類庫)
     * 那這類庫就能夠時候在進行實現
     * 開始的時候咱們就能夠對整個項目是否可行,經過接口就可模擬出來
     */
    
})()

閉包

  1. 門戶大開類型程序員

  2. 用命名規範區別私有和共有的方式數組

  3. 閉包閉包

/**
 * 信息的隱藏是最終的目的,封裝只不過是隱藏的一種方法 
 */
(function(){
    /**
     * 1.門戶大開類型
     * 2.用命名規範區別私有和共有的方式
     * 3.閉包
     */
    //門戶打開型
    function Person(age,name){
        this.name = name;
        if(!this.checkAge(age)){
            throw new Error("年齡必須在0到150之間");
        }
        this.age = age;
    }
    //var p = new Person(-10,"JIM");
    //alert(p.age)
    //解決上述問題
    Person.prototype = {
        checkAge:function(age){
            if(age>0 && age < 150){
                return true;
            }else{
                return false;
            }
        }
    }
    Person.prototype["getName"] = function(){
        return this.name || "USPCAT.COM";    
    }
    //var p = new Person(-10,"JIM");
    var p = new Person(27,"JIM");
    var p2 = new Person(27);
    alert(p2.getName());

})()

上面這種門戶大開的都是公用的不是很好,應該提早作好閉包架構

(function(){
    //用命名規範來區別私有和共有變量
    function Person(name,age,email){
        //定義私有變量
        this._name;//私有
        this._age;//私有
        this.setName(name);
        this.setAge(age);
        this.email = email;//共有
        
    }
    Person.prototype = {
        setName:function(name){
            this._name = name;
        },
        setAge :function(age){
            if(age>0 && age < 150){
                this._age = age;
            }else{
                throw new Error("年齡必須在0到150之間");
            }            
        }
    }
    var p = new Person("JIM",-1,"JIM@USPCAT.COM");
})()
/**
 * 閉包實現封裝
 */
(function(){
    function person(name,age,email,sex){
        this.email = email;//public 變量
        //get
        this.getName = function(){
            return this.name;
        }
        this.getAge = function(){
            return this.age;
        }        
        //set
        this.setName = function(name){
            this.name = name
        }
        this.setAge = function(age){
            if(age>0 && age < 150){
                this.age = age
            }else{
                throw new Error("年齡必須在0到150之間");
            }                
        }
        var _sex = "M";//這也是私有變量的編寫方式
        this.getSex = function(){
            return _sex;
        }
        this.setSex = function(){
            _sex = sex
        }
        this.init = function(){
            this.setName(name);
            this.setAge(age);
        }
        this.init();
    }
    //ceshi 
    var p = new person("JIM",-1,"www.USPCAT@126.COM")
})()
/**
 * 普通的屬性和函數是做用早對象上的
 * 而靜態的函數是定義到類上面的
 */
(function(){
    function Person(name,age){
        this.name = name;
        this.showName = function(){
            alert(this.name)
        }
    }
    //第一種靜態函數的寫法
    Person.add = function(x,y){
        return x+y;
    }
    //alert(Person.add(10,20))
    //第二種方式
    //用類中類的方式完成沒一個對象全擁有相同的屬性和闡述
    var cat = (function(){
        //私有靜態屬性
        var AGE = 10;
        //私有函數
        function add(x,y){
            return x+y;
        }
        return function(){
            this.AGE = AGE;
            this.add = function(x,y){
                return add(x,y)
            }
        }
    })()
    alert(new cat().add(1,2)+"  "+new cat().AGE);
    alert(new cat().AGE);
    /**
     * 1.保護內部數據完整性是封裝一大用處
     * 2.對象的重構變得很輕鬆,(若是沒有封裝你感動正在用這的代碼嗎?)
     * 3.弱化模塊直接的耦合
     * 弊端
     * 私有的方法他會變得很難進行單元測試
     * 使用封裝就會意味着與複雜的代碼打交道
     * 最大問題是封裝在javascript中是很難實現的
     */
})()

單體模式

1.普通的單體
2.具備局部變量的強大單體
3.惰性單體
4.分支單體dom

函數的鏈式調用

工廠模式

橋樑模式

門面模式

組合模式

適配模式

裝飾者

享元模式

代理模式

責任鏈模式

命令模式

觀察者模式

類引擎

相關文章
相關標籤/搜索