設(shè)計(jì)模式

分類(lèi)

創(chuàng)建型

創(chuàng)建對(duì)象時(shí)嘱巾,不再直接實(shí)例化對(duì)象憨琳;而是根據(jù)特定場(chǎng)景,由程序來(lái)確定創(chuàng)建對(duì)象的方式旬昭,從而保證更高的性能篙螟、更好的架構(gòu)優(yōu)勢(shì)。創(chuàng)建型模式主要有簡(jiǎn)單工廠(chǎng)模式(并不是23種設(shè)計(jì)模式之一)问拘、工廠(chǎng)方法遍略、抽象工廠(chǎng)模式、單例模式骤坐、生成器模式和原型模式绪杏。

結(jié)構(gòu)型

用于幫助將對(duì)個(gè)對(duì)象組織成更大的結(jié)構(gòu)。結(jié)構(gòu)型模式主要有適配器模式纽绍、橋接模式蕾久、組合器模式、裝飾器模式拌夏、門(mén)面模式僧著、享元模式和代理模式。

行為型

用于幫助系統(tǒng)間各對(duì)象的通信辖佣,以及如何控制復(fù)雜系統(tǒng)中的流程霹抛。行為模式主要有命令模式、解釋器模式卷谈、迭代器模式、中介者模式霞篡、備忘錄模式世蔗、觀察者模式、狀態(tài)模式朗兵、策略模式污淋、模板模式和訪(fǎng)問(wèn)者模式。

單例模式

如果一個(gè)類(lèi)始終只能創(chuàng)建一個(gè)實(shí)例余掖,則這個(gè)類(lèi)被稱(chēng)為單例類(lèi)寸爆,這種模式就被稱(chēng)為單例模式。
Spring推薦將所有業(yè)務(wù)邏輯組件、DAO組件赁豆、數(shù)據(jù)源組件等配置成單例的行為方式仅醇,因?yàn)檫@些組件無(wú)需保存任何用戶(hù)狀態(tài)。
為了保證一個(gè)類(lèi)只能產(chǎn)生一個(gè)實(shí)例魔种,程序不能允許自由創(chuàng)建該類(lèi)的對(duì)象析二,只需要使用private修飾該類(lèi)的構(gòu)造器,從而將該類(lèi)的構(gòu)造器隱藏起來(lái)节预。同時(shí)提供一個(gè)public方法作為該類(lèi)的訪(fǎng)問(wèn)點(diǎn)叶摄,用于創(chuàng)建該類(lèi)的對(duì)象,且該方法必須使用static修飾(因?yàn)檎{(diào)用該方法之前還不存在對(duì)象安拟,因此調(diào)用該方法的不可能是對(duì)象蛤吓,只能是類(lèi))。除此之外糠赦,該類(lèi)還必須緩存已經(jīng)創(chuàng)建的對(duì)象会傲,否則該類(lèi)無(wú)法知道是否曾經(jīng)創(chuàng)建過(guò)實(shí)例,也就無(wú)法保證只創(chuàng)建一個(gè)實(shí)例愉棱。為此該類(lèi)需要使用一個(gè)靜態(tài)屬性來(lái)保存曾經(jīng)創(chuàng)建的實(shí)例唆铐,且該屬性需要被靜態(tài)方法訪(fǎng)問(wèn),所以該屬性也應(yīng)使用static修飾奔滑。

class Singleton {
   //使用一個(gè)類(lèi)變量緩存曾經(jīng)創(chuàng)建的實(shí)例
   private static Singleton instance;
   // 將構(gòu)造器使用private修飾艾岂,隱藏該構(gòu)造器
   private Singleton(){}
   //提供一個(gè)靜態(tài)方法,用于返回Singleton實(shí)例
   //該方法可以加入自定義的控制朋其,保證只產(chǎn)生一個(gè)Singleton對(duì)象
   public static Singleton getInstance(){
       //如果instance為null王浴,表明不曾創(chuàng)建Singleton對(duì)象
       //如果instance不為null,則表明已創(chuàng)建了Singleton對(duì)象梅猿,將不會(huì)執(zhí)行該方法
       if(instance == null){
           instance = new Singleton();
       }
       return instance;
   }
}

工廠(chǎng)

  • 簡(jiǎn)單工廠(chǎng)
  • 工廠(chǎng)方法
  • 沖向工廠(chǎng)
    定義一個(gè)Factory專(zhuān)門(mén)用于生產(chǎn)類(lèi)對(duì)象氓辣。使用方通過(guò)Factory調(diào)用對(duì)應(yīng)的類(lèi)對(duì)象,將使用者和類(lèi)對(duì)象解耦袱蚓,由統(tǒng)一工廠(chǎng)耦合钞啸。如果需要更改類(lèi)對(duì)象,不需要更改工廠(chǎng)的調(diào)用者喇潘。
    如果工廠(chǎng)直接生產(chǎn)被調(diào)用對(duì)象体斩,那就是簡(jiǎn)單工廠(chǎng)模式;如果工廠(chǎng)生產(chǎn)了工廠(chǎng)對(duì)象颖低,那就是會(huì)升級(jí)成抽象工廠(chǎng)模式絮吵。

代理模式

InvokationHandler實(shí)現(xiàn)

public class MyInvokationHandler implements InvocationHandler {
   //需要被代理的對(duì)象
   private Object target;

   public void setTarget(Object target) {
       this.target = target;
   }

   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       TxUtil tx = new TxUtil();
       tx.beginTx();

       Object result = method.invoke(target,args);
       tx.endTx();
       return result;
   }
}
public class MyProxyFactory {

   //為指定target生成動(dòng)態(tài)代理對(duì)象
   public static Object getProxy(Object target) throws Exception{
       //創(chuàng)建一個(gè)MyInvokationHandler對(duì)象
       MyInvokationHandler handler = new MyInvokationHandler();

       //為MyInvokationHandler設(shè)置target對(duì)象
       handler.setTarget(target);
       //創(chuàng)建并返回一個(gè)動(dòng)態(tài)代理
       return Proxy.newProxyInstance(target.getClass().getClassLoader() , >target.getClass().getInterfaces(),handler);
   }
}

命令模式

思考一種場(chǎng)景,某個(gè)方法需要完成某一個(gè)功能忱屑,完成這個(gè)功能的參數(shù)要求可以變化蹬敲,具體執(zhí)行的代碼也可以變化暇昂,即需要把“處理行為”也作為一個(gè)參數(shù)傳入方法。

public interface Command {
   void process(int[] target);
}
public class ProcessArray {
   public void each(int[] target,Command cmd){
       cmd.process(target);
   }
}
  public class CommandTest {
    public static void main(String[] args) {
       ProcessArray pa = new ProcessArray();
       int[] target = {3,-4,6,4};
       pa.each(target, new Command() {
           @Override
           public void process(int[] target) {
               for(int tmp : target){
                   System.out.println("迭代輸出目標(biāo)數(shù)組的元素:"+ tmp);
               }
           }
       });
   }
}

策略模式

思考一種場(chǎng)景伴嗡,某書(shū)店需要提供打折場(chǎng)景(vip折扣急波,舊書(shū)兌換折扣。闹究。幔崖。)
其用意是針對(duì)一組算法,將每一個(gè)算法封裝到具有共同接口的獨(dú)立的類(lèi)中渣淤,從而使得它們可以相互替換赏寇。策略模式使得算法可以在不影響到客戶(hù)端的情況下發(fā)生變化。策略模式是對(duì)算法的包裝价认,是把使用算法的責(zé)任和算法本身分割開(kāi)來(lái)嗅定,委派給不同的對(duì)象管理。策略模式通常把一個(gè)系列的算法包裝到一系列的策略類(lèi)里面用踩,作為一個(gè)抽象策略類(lèi)的子類(lèi)渠退。用一句話(huà)來(lái)說(shuō),就是:“準(zhǔn)備一組算法脐彩,并將每一個(gè)算法封裝起來(lái)碎乃,使得它們可以互換”。

橋接模式

假如有一個(gè)飯店提供菜單:牛肉面惠奸、豬肉面...選擇添加辣椒時(shí):無(wú)辣梅誓、微辣、中辣...
此時(shí)可以選擇橋接模式(把變化的部分抽象出來(lái))然后使得變化部分與主類(lèi)分離開(kāi)來(lái)佛南;通過(guò)組合滿(mǎn)足業(yè)務(wù)的需要梗掰。

觀察者模式

觀察者模式定義了對(duì)象間的一對(duì)多依賴(lài)關(guān)系,讓一個(gè)或者多個(gè)觀察者對(duì)象觀察一個(gè)主題對(duì)象嗅回。當(dāng)主題對(duì)象的狀態(tài)發(fā)生變化時(shí)及穗,系統(tǒng)能通知所有的依賴(lài)于次對(duì)象的觀察者對(duì)象,從而使得觀察者對(duì)象能夠自動(dòng)更新绵载。

觀察者模式主要的4個(gè)角色:

  • 被觀察者的抽象基類(lèi)埂陆。一般有java.util.Observable提供。
  • 觀察者接口 一般由java.util.Observer提供
  • 被觀察者實(shí)現(xiàn)類(lèi) Product
  • 觀察者實(shí)現(xiàn)類(lèi)
//被觀察者
public class Product extends Observable {

    //定義兩個(gè)成員變量
    private String name;
    private double price;

    public Product(){}

    public Product(String name,double price){
        this.name = name;
        this.price = price;
    }

    public String getName(){
        return name;
    }

    //當(dāng)程序調(diào)用name的setter方法來(lái)修改Product的name成員變量時(shí)娃豹,程序自然觸發(fā)該對(duì)象上注冊(cè)的所有觀察者
    public void setName(String name){
        this.name = name;
        this.setChanged();
        notifyObservers(name);
    }

    public double getPrice(){
        return price;
    }

    public void setPrice(double price){
        this.price = price;
        this.setChanged();
        notifyObservers(price);
    }
}

//觀察者實(shí)現(xiàn)
public class NameObserver implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        if( arg instanceof String ){
            String name = (String) arg;
            JFrame f = new JFrame("觀察者");
            JLabel l = new JLabel("名稱(chēng)改變?yōu)椋? + name);
            f.add(l);
            f.pack();
            f.setVisible(true);
            System.out.println("名稱(chēng)觀察者:" + o + "物品名稱(chēng)已經(jīng)改變?yōu)椋? + name);
        }
    }
}
//注冊(cè)觀察者至被觀察者
public class Main {
    public static void main(String[] args) {
        Product p = new Product("電視劇",176);

        NameObserver no = new NameObserver();
        PriceObserver po = new PriceObserver();

//        p.registObserver(no);
//        p.registObserver(po);
        p.addObserver(no);
        p.addObserver(po);

        p.setName("書(shū)桌");
        p.setPrice(345f);

    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末猜惋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子培愁,更是在濱河造成了極大的恐慌,老刑警劉巖缓窜,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件定续,死亡現(xiàn)場(chǎng)離奇詭異谍咆,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)私股,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)摹察,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人倡鲸,你說(shuō)我怎么就攤上這事供嚎。” “怎么了峭状?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵克滴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我优床,道長(zhǎng)劝赔,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任胆敞,我火速辦了婚禮着帽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘移层。我一直安慰自己仍翰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布观话。 她就那樣靜靜地躺著予借,像睡著了一般。 火紅的嫁衣襯著肌膚如雪匪燕。 梳的紋絲不亂的頭發(fā)上蕾羊,一...
    開(kāi)封第一講書(shū)人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音帽驯,去河邊找鬼龟再。 笑死,一個(gè)胖子當(dāng)著我的面吹牛尼变,可吹牛的內(nèi)容都是我干的利凑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼嫌术,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼哀澈!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起度气,我...
    開(kāi)封第一講書(shū)人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤割按,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后磷籍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體适荣,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡现柠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弛矛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片够吩。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖丈氓,靈堂內(nèi)的尸體忽然破棺而出周循,到底是詐尸還是另有隱情,我是刑警寧澤万俗,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布湾笛,位于F島的核電站,受9級(jí)特大地震影響该编,放射性物質(zhì)發(fā)生泄漏迄本。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一课竣、第九天 我趴在偏房一處隱蔽的房頂上張望嘉赎。 院中可真熱鬧,春花似錦于樟、人聲如沸公条。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)靶橱。三九已至,卻和暖如春路捧,著一層夾襖步出監(jiān)牢的瞬間关霸,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工杰扫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留队寇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓章姓,卻偏偏與公主長(zhǎng)得像佳遣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子凡伊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355