1. 程式人生 > 其它 >斑碼教育web前端課堂筆記-第63天-設計模式第一天

斑碼教育web前端課堂筆記-第63天-設計模式第一天

技術標籤:斑碼筆記web前端筆記前端前端

設計模式第一天

一、設計模式

軟體中的名詞:

  • 工具庫:一些常用方法的封裝,這些方法之間彼此沒有聯絡,jQuery、underscore
  • 框架:程式碼的半成品,彼此之間存在非常緊密的聯絡, vue
  • 架構:一套大型專案的設計思路
  • 設計模式: 前人的經驗,代表了最佳的實踐方式。GOF。 最初設計模式有23種,目前遠超23種。

1.1 設計模式簡介

他是一套編目分明,廣為人知,可複用的程式碼經驗的總結,代表了軟體設計的最佳實踐方式。

1.2 設計原則

  • 開閉原則: 對擴充套件開放,對修改關閉
  • 單一職責原則:一個類只負責一個事
  • 裡式替換原則:一個父類能用的地方,子類一定可以使用
  • 依賴倒置原則:抽象不應該依賴於細節,細節依賴於抽象
  • 介面隔離原則:使用多個專門介面取代單一介面
  • 迪米特原則: 一個類實現的功能不應該依賴於其他類
  • 合成複用原則:儘可能使用物件的組合(contiain)和聚合(has),而不是繼承(is)

高內聚低耦合,擴充套件開放,修改關閉。

1.3 設計模式的分類

  • 建立型設計模式: 解決物件的建立問題
  • 結構型設計模式: 解決物件和類的組合問題
  • 行為型設計模式:解決物件和類的耦合,職責分配的問題

二、工廠模式

解決物件的建立問題

2.1 簡單工廠

建立一個產生物件的函式

demo:

// 獲得#box物件
var box = document.getElementById
('box'); // 獲得class var container = document.getElementsByClassName('container')[0]; // 獲得li物件 var lis = document.getElementsByTagName('li'); // jquery中 $('css選擇器') // 簡單工廠 function $(selector) { return document.querySelectorAll(selector); } // 通過工廠獲得物件 console.log($('#box')); console.log($('.container'
)); console.log($('li')); var xiaoming = { name: '小明', age: 13, sex: '男' } var lili = { name: '莉莉', age: 18, sex: '女' } var zhangsan = { name: '張三', age: 20, sex: '男' } function people(name, age, sex) { var obj = { name: name, age: age, sex: sex } return obj; } var lisi = people('李四', 20, '男'); var meimei = people('美美', 20, '女');

2.2 寄生增強工廠

定義一個新的工廠,在該工廠內例項化其他工廠,並對其進行增強改造

demo:

<script>
    // 產生人類
    function People(name, sex, age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    // 說話
    People.prototype.say = function() {
        console.log('i can say');
    }

    function factory(name, sex, age) {
        // 寄生
        var people = new People(name, sex, age);
        // 增強
        people.code = function() {
            console.log('我可以程式設計');
        }
        people.money = 10000000000;
        return people;
    }

    var xiaoming = factory('小明', '男', 18);
    console.log(xiaoming);
</script>

2.3 工廠方法

通過一個工廠管理很多個工廠

demo:

<script>
    // 建立人的工廠
    function People(name, sex, age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    // 建立狗狗的工廠
    function Dog(name, sex, age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    // 建立美女的工廠
    function Girl(name, sex, age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    // 封裝工廠,可以根據引數的不同調用不同工廠
    function FactoryMethod(type, name, sex, age) {
            if (type == 'people') {
                return new People(name, sex, age);
            } else if (type == 'dog') {
                return new Dog(name, sex, age);
            } else if (type == 'girl') {
                return new Girl(name, sex, age);
            }
    }

    var xiaoming = FactoryMethod('people', '小明', '男', 20);
    var wangcai = FactoryMethod('dog', '旺財', '公', 3);
    var xiaomei = FactoryMethod('girl', '小美', '女', 22);
    console.log(xiaoming);
    console.log(wangcai);
    console.log(xiaomei);
</script>

三、原型和繼承

3.1 原型和原型鏈

原型是每一個函式都擁有的屬性(prototype),該屬性指向了一個公共的物件,該物件形成一個公共的區域,該區域內的所有屬性和方法可以被函式產生的例項所訪問到。為了減少記憶體的佔用,設計類的時候,要將方法寫在原型中,同樣,所有物件共用的屬性也需要寫在原型中。

由於函式也是物件,物件擁有原型物件,形成原型鏈,屬性和方法的查詢遵循原型鏈的自下而上的查詢規則。

3.2 繼承

  • 鏈式繼承

    將子類的原型指向父類的例項
    
  • 建構函式繼承

    解決重複問題
    父類.apply(this, arguments)
    
  • 組合繼承: 鏈式繼承 + 建構函式繼承

  • 寄生繼承

    A是父類
    B是子類
    
    function x(A, B) {
    	function F() {}
    	F.prototype = A.prototype;
    	B.prototype = new F();
    }
    
  • 寄生組合繼承: 寄生 + 建構函式

3.3 安全類

安全類: 不管使用new還是直接呼叫,返回的都是例項化得到的物件

demo:

<script>
    // 產生人類
    function People(name, sex, age) {
        // 判斷該物件是否由People所產生
        if (!(this instanceof People)) {
            return new People(name, sex, age);
        }
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    // 說話
    People.prototype.say = function() {
        console.log('i can say');
    }

    var xiaoming = new People('小明', '男', 20);  
    console.log(xiaoming);  
    var xiaomei = People('小美', '女', 22);
    console.log(xiaomei);
</script>

四、單例設計模式

一個類只產生一個例項化物件

分析:

  1. 類是函式
  2. 建構函式不能暴露在全域性下,但是還需要能夠使用----閉包

閉包:

函式內部返回一個函式,該函式引用了函式內部的變數,導致變數不能夠被釋放,延長了變數的宣告週期,和全域性相同,但是由於這個變數屬於函式內的區域性變數,在全域性中不能夠被訪問到的,只能通過向外暴露的函式來訪問該變數

閉包:

function demo() {
    var a = 1; // 此時的a只能通過返回的函式進行訪問,保護了,限制了a的訪問方式
    return function() {
        console.log(a++);
    }
    
}

var f1 = demo();
f1(); // 1
f1(); // 2 

var f2 = demo();
f2(); // 1
f2(); // 2


var fn = (function() {
    var a = 1;
    return function() {
    console.log(a++);
    }
})();

fn();
fn();
fn();

4.1 簡單單例

demo:

var Single = (function() {
    // 產生人類
    function People(name, sex, age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    // 說話
    People.prototype.say = function () {
        console.log('i can say');
    }
    // 生成一個物件
    var obj = new People();
    // console.log(obj);
    // 返回函式
    return function(name, sex, age) {
        // obj.name = name;
        // obj.sex = sex;
        // obj.age = age;
        People.apply(obj, arguments);
        return obj;
    }
})()


var xiaoming = Single('小明', '男', 20);
console.log(xiaoming);
var xiaomei = Single('小美', '女', 22);
console.log(xiaomei);
console.log(xiaomei == xiaoming);

4.2 惰性單例

按需例項化,只有呼叫一次才會例項化類

demo:

var Single = (function() {
    // 產生人類
    function People(name, sex, age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    // 說話
    People.prototype.say = function () {
        console.log('i can say');
    }
    // 生成一個物件
    var obj = null;
    // 返回函式
    return function(name, sex, age) {
        if (obj instanceof People) {
            People.apply(obj, arguments);
            return obj;
        } else {
            return obj = new People(name, sex, age);
        }
    }
})()


var xiaoming = Single('小明', '男', 20);
console.log(xiaoming);
var xiaomei = Single('小美', '女', 22);
console.log(xiaomei);
console.log(xiaomei == xiaoming);

五、常量

字面量:儲存一個值,值是一個基礎型別的值,值不會改變

常量:值不能被修改

demo:

<script>
    // ES6
    // const a = 1;
    // a = 2;


    // ES3 
    var fn = (function() {
        var obj = {
            a: 1,
            b: 2,
            c: 3,
            d: {
                name: 'xxoo'
            }
        }

        return function(k) {
            return obj[k];
        }
    })()
    // 常量只針對於非引用型別有效
    // 上面的a,b,c就是三個變數
    console.log(fn('a'));
    console.log(fn('b'));
    console.log(fn('c'));
    // 無效
    fn('d').name = 'abc';
    console.log(fn('d'));


    // ES5---凍結物件,屬性值為引用型別的時候,引用型別可以進行增刪改查
    var obj = {
        a: 1,
        b: 2,
        c: 3,
        d: {
            name: 'xxoo'
        }
    }

    // 凍結物件
    Object.freeze(obj);
    console.log(obj.a);
    console.log(obj.b);
    console.log(obj.c);
    obj.a = 123;
    console.log(obj.a);
    obj.d.name = 'abc';
    obj.d.sex = 'abc';
    console.log(obj.d);
    obj.d = {a: 1};
    console.log(obj.d);

</script>

在這裡插入圖片描述