開放封閉原則之模式的黃金法則

開放-封閉原則應該算是這幾個原則裏面最容易理解的一個。它的宗旨就是:
若是你想擴展或者改變一個程序的功能,能夠增長代碼,可是不能改變程序的源碼。
若是,是對於那些碼農來講,最快捷的辦法就是改變源碼,可是咱們面向的是更復雜的項目,咱們的目的不是當碼農,而是要作一名代碼藝術家,想完成一件藝術品同樣去完成咱們的項目。
拿裝飾者模式的例子來講吧。 若是咱們想改變onload的函數,即,其餘小夥伴,有可能已經在onload上面綁定好,咱們能夠翻閱onload代碼,進行修改。 可是,這個擴展性簡直啦!!!
從裝飾者模式能夠知道,咱們可使用引用裝飾進行改動。ajax

var fn = window.onload;
var change = function(){
    fn();
    conosle.log("整潔代碼");
}
window.onload = function(){  
    change();
}

固然,咱們也可使用AOP,進行一個裝飾,將原來代碼實現的功能徹底保留,只在外部添加一些代碼。
另外,if語句就是開放封閉原則的死敵.
這個是狀態模式中的一個例子。函數

if(state === "auto"){
            console.log("制熱");
            state = "hot";
        }else if(state === "hot"){
            console.log("製冷");
            state = "cold";
        }else if(state === "cold"){
            console.log("送風");
            state = "wind";
        }else if(state === "wind"){
            console.log("除溼");
            state = "dry";
        }else if(state === "dry"){
            console.log("自動");
            state = "auto";
        }

能夠從上面的代碼看出,若是功能繼續發生變化,你必須作的就是改動原來代碼的內容,這是極不可取的。 因此依照開放封閉原則,咱們須要進行優化,能夠修改成這樣優化

//定義狀態
var Auto= function(button){
    this.turn = button;
}
Auto.prototype.press= function(){
    console.log('制熱');
    this.turn.setState("hot");
}
var Hot = function(button){
    this.turn = button;
}
Hot.prototype.press= function(){
    console.log('製冷');
    this.turn.setState("cold");
}
var Cold = function(button){
    this.turn = button;
}
Cold.prototype.press= function(){
    console.log('送風');
    this.turn.setState("wind");
}
var Wind = function(button){
    this.turn = button;
}
Wind.prototype.press= function(){
    console.log('除溼');
    this.turn.setState("dry");
}
var Dry = function(button){
    this.turn = button;
}
Dry.prototype.press= function(){
    console.log('自動');
    this.turn.setState("auto");
}
//定義狀態倉庫
var Remoter = function(){
    this.auto = new Auto(this);
    this.hot = new Hot(this);
    this.cold = new Cold(this);
    this.wind = new Wind(this);
    this.dry = new Dry(this);
    this.state = "auto";
}
Remoter.prototype.setState = function(state){
    this.state=state;
}
Remoter.prototype.press = function(){
    this[this.state].press();  //執行對應狀態的press
}
Remoter.prototype.init = function(){  //定義執行者
    document.querySelector('.switch').addEventListener("click",()=>{
        this.press();
    },false);
}
new Remoter.init();  //初始化

即,使用對象的多態性,消除條件分支語句。this

處理開放封閉模式的特例

咱們都是人,不可能一開始都寫出完美的代碼。但咱們在寫程序的時候,要永遠的給本身留一手,以便後面改動的須要。 在模板模式裏,咱們給特殊性留了一條後路, 咱們使用鉤子方法,經過外部的設置,咱們能夠獲得不用的結果。
固然,咱們還可使用callback函數,執行本身想要作的功能,好比在$.ajax調用的時候,咱們添加回調函數,執行本身想要的函數功能,這些都是很棒的實現開放封閉模式原則的辦法。prototype

最後一點

這裏想說的就是,原則是一份指導,可以指引你的代碼結果怎樣作,能夠達到最優的形式,但,事實上,咱們遵不遵照,是徹底取決於我的而言的。 並且,有時候咱們寫程序,真的沒必要過度追求設計,由於咱們是完成用戶的交付的需求,若是一味追求設計,無疑增長代碼的難度,和實現的時間。因此,一切跟着感受走,咱們寫程序不也是憑感受寫的嗎?設計

相關文章
相關標籤/搜索