淺談設計模式的學習(上)

做爲一個開發人員,能寫出一個漂亮可擴展的代碼,絕對是一件使人愉快的事情。那設計模式就是一門必修課!java

  本文就本身學習設計模式的一點經歷作一個記錄。程序員

  本人在讀大學時,爲了學習設計模式就買了一本《java與模式》的數據,書籍有一千多頁很重、並且價格不菲。沒辦法,花那麼多錢買的不看豈不浪費。因而天天早上讀一章,堅持幾個月我終於讀完了。這幾個月真是煎熬啊,幾個月下來,回憶一下彷佛本身真得也沒收穫到什麼,很悍然啊。難道是書籍很差嗎仍是我讀的不認真?其實在我如今看來都不是。而爲何讀完了卻什麼也沒收穫到呢?我覺着:第一是由於我當時編碼的經歷不夠豐富、第二沒有理解設計模式的用途和思想。因此學了有點白學。至於編碼經驗這個只能靠本身多練習,沒什麼好說的。這裏就說說我對設計模式學習的一點理解吧spring

  一、學習設計模式,首先要理解設計模式究竟是什麼。數據庫

       曾經我一度認爲,一個設計模式就是一個固定結構的代碼,好比觀察者模式,就是在一個被觀察者裏邊維護一個集合,將觀察者放進這個集合裏,一有事件觸發便遍歷集合裏的觀察者調用他們的某個方法。(若是你也這麼理解,那趕快收手吧,不然你會很痛苦的)這麼理解對嗎?至少我如今認爲是打錯特錯的。總共有23種設計模式,是很少,可是若是把每一個設計模式理解成一個代碼結構的話確定會很亂,由於有好多設計模式代碼結構很類似,好比代理模式和裝飾者模式,這麼理解只會讓你混亂搞不清楚,你認爲呢?。那咱們該怎麼理解設計模式呢,我的覺着哈,一個設計模式是針對的一個應用場景,好比代理模式和裝飾模式,代碼結構很類似,可是代理模式的用途是爲了添加別的功能,好比spring的aop就是代理模式的一個很好地應用,項目中有不少數據庫操做,可是不管是曾、刪、改操做前都要打開事務,操做後要提交事務,因此採用代理,將這打開和關閉事務統一管理,這就是至關於在增刪改操做先後添加了別的操做;而裝飾模式呢,他是增強和裝飾某一個已有的功能,最經典的應用就是jdk裏的輸入輸出流了,好比BufferedInputStream就是給InputStream增強了基於緩存讀寫數據流的功能。因此這裏我再強調一遍,設計模式是針對不一樣的應用場景而不是一個代碼結構(千萬不要經過代碼結構去區分不一樣的設計模式,就像前邊說的代理和裝飾,代碼結構類似,可是應用目的是不一樣的)。切記其珍惜啊編程

二、學習設計模式,首先要清楚設計模式能幹什麼。設計模式

     學習設計模式,你須要內心承認他,可是對於不少像我同樣的一些初學者吧,由於體會不到他的好處,內心就沒有去承認他,因此也無從踏心的去學習了。設計模式有什麼好處呢?能幹什麼呢?在這裏我舉個例子:(但願你看了也能有所感觸)
數組

     咱們常常要遍歷一個集合,這個集合多是ArrayList也多是LinkedList,學過數據結構的都知道這兩個集合的數據結構是不一樣的,數據結構不一樣,因此遍歷方式確定也不一樣,這樣現實開發中你要記住每個數據結構的遍歷方式,若是數據結構更多,那豈不是很累啊(相信你會贊同吧)。可是現實中你遍歷集合,由於集合數據結構的不一樣而採用不一樣的遍歷方式了嗎?確定沒有吧,不管是基於數組仍是鏈表的集合,咱們用一個Iterator搞定,你只須要在乎iterator的兩個方法(hasNext()和next())而沒必要理會集合的內部數據結構。簡單吧,爽嗎,反正我是感受很爽,這就是設計模式的一個好處。這裏採用的什麼設計模式呢?不知道能想到嗎,工廠方法模式。ArrayList和LinkedList做爲工廠生產本身的Iterator,由於只有本身瞭解本身內部數據結構和遍歷方式。這裏他們建立的迭代器都實現了Iterator接口,咱們是針對的接口編程,因此體會不到不一樣集合建立的迭代器的不一樣。(如今你是否定可了設計模式啊,是否定識到他是有用的呢,若是由於這篇文章讓你承認了它,真是個人榮幸啊,哈哈)緩存

  上邊這個例子能夠說是設計模式可以封裝變化,讓客戶端調用(就是你調用你用設計模式編寫的類的地方,好比main方法裏)不受變化的影響;下邊我再舉個例子,說一下設計模式另外一個能幹的事------對方便擴展(就是開閉原則)數據結構

    你們知道開關和燈泡,開關都有一個打開關閉的功能,不管你是聲控開關仍是其餘各類類型的開關;燈泡都有一個亮和滅的功能,無亂你是白熾燈、閃關燈的。這樣咱們能夠分別爲燈泡和開關提取一個接口,燈泡接口和開關接口,燈泡接口提供亮和滅方法,開關提供開和關方法。代碼以下:ide

快關接口:

public interface Switch {

    public void setLight(Light light);

    public void open();

    public void close();
}
1 public interface Light {
2 
3     public void lightUp();
4     
5     public void LightOff();
6 }

在這裏咱們再提供一個普通的快關實現:

 1 public class NormalSwitch implements Switch{
 2 
 3     private Light light;
 4     
 5     public void setLight(Light light){
 6         this.light=light;
 7     }
 8     
 9     @Override
10     public void open() {
11         light.lightUp();
12     }
13     
14     @Override
15     public void close() {
16         light.LightOff();
17     }
18 }

這是一個普通的燈泡實現:

public class NormalLight implements Light {

    @Override
    public void lightUp() {
        System.out.println("燈亮了");
    }

    @Override
    public void LightOff() {
        System.out.println("燈滅了");
    }

}

接下來是客戶端的調用了:

public class Main {

    public static void main(String[] args) {
        Light light = new NormalLight();

        Switch swtich= new NormalSwitch();

        swtich.setLight(light);

        swtich.open();

        swtich.close();
    }

}

接下來講一說這麼作如何有利於擴展了,好比我要換燈泡了,換個高端大氣上檔次的:

 1 public class LuxuriousLight implements Light {
 2 
 3     @Override
 4     public void lightUp() {
 5         System.out.println("燈泡豪華的亮了");
 6     }
 7 
 8     @Override
 9     public void LightOff() {
10         System.out.println("燈泡驕傲的滅了");
11     }
12 
13 }

對於客戶端要怎麼變化呢?來吧看一看:

 1 public class Main {
 2 
 3     public static void main(String[] args) {
 4         Light light = new LuxuriousLight();//NormalLight();
 5 
 6         Switch swtich= new NormalSwitch();
 7 
 8         swtich.setLight(light);
 9 
10         swtich.open();
11 
12         swtich.close();
13     }
14 
15 }

看,咱們以前的普通燈泡沒有收到任何影響吧,若是還有別的客戶端使用了普通的燈泡,咱們新添加的奢侈的燈泡絕對不會影響到他們的邏輯。固然有朋友可能會說,客戶端不也是把new NormalLight改爲了new LuxuriousLight了嗎,呵呵,這點改動不無妨,主要是咱們後邊經過開關關閉點燈的邏輯沒有變化。這不管是應對變化仍是可擴展性都是頗有幫助的。在這裏不知道你想到了這是什麼設計模式嗎?沒錯,就是橋接模式,簡單吧。

  學習設計模式有一點特別特別重要的一點,就是抽象思惟,這是整個設計模式的基石,因爲時間緣由,下次再續。O(∩_∩)O~

  做爲程序員,身體是一切的根本,注意身體健康,五一快樂哦

相關文章
相關標籤/搜索