7.設(shè)計(jì)模式階段總結(jié)

設(shè)計(jì)模式總結(jié)

回顧軟件設(shè)計(jì)原則

設(shè)計(jì)模式簡(jiǎn)介

設(shè)計(jì)原則 解釋
開(kāi)閉原則 對(duì)擴(kuò)展開(kāi)放箍鼓,對(duì)修改關(guān)閉呵曹。
依賴倒置原則 通過(guò)抽象使各個(gè)類(lèi)或者模塊不相互影響,實(shí)現(xiàn)松耦合铐殃。
單一職責(zé)原則(6大原則不包括他) 一個(gè)類(lèi)背稼、接口蟹肘、方法只做一件事俯树。
接口隔離原則 盡量保證接口的純潔性,客戶端不應(yīng)該依賴不需要的接口阳欲。
迪米特法則 又叫最少知道原則球化,一個(gè)類(lèi)對(duì)其所依賴的類(lèi)知道得越少越好瓦糟。
里氏替換原則 子類(lèi)可以擴(kuò)展父類(lèi)的功能但不能改變父類(lèi)原有的功能菩浙。
合成復(fù)用原則 盡量使用對(duì)象組合劲蜻、聚合,而不使用繼承關(guān)系達(dá)到代碼復(fù)用的目的轧苫。

經(jīng)典框架都在用設(shè)計(jì)模式解決問(wèn)題

設(shè)計(jì)模式名稱 舉例
工廠模式 BeanFactory
裝飾器模式 BeanWrapper
代理模式 AopProxy
委派模式 DispatcherServlet
策略模式 HandlerMapping
適配器模式 HandlerAdapter
模板模式 JdbcTemplate
觀察者模式 ContextLoaderListener

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

類(lèi)型 名稱 英文
創(chuàng)建型模式 工廠模式 Factory Pattern
創(chuàng)建型模式 單例模式 Singleton Pattern
創(chuàng)建型模式 原型模式 Prototype Pattern
結(jié)構(gòu)型模式 適配器模式 Adapter Pattern
結(jié)構(gòu)型模式 裝飾器模式 Decorator Pattern
結(jié)構(gòu)型模式 代理模式 Proxy Pattern
行為性模式 策略模式 Strategy Pattern
行為性模式 模板模式 Template Pattern
行為性模式 委派模式 Delegate Pattern
行為性模式 觀察者模式 Observer Pattern

工廠模式

簡(jiǎn)單工廠

  • 簡(jiǎn)單工廠模式(Simple Factory Pattern)
    • 課程為例,課程為例 有java課程 ,有python課程等鳄袍,課程Factory 創(chuàng)建課程拗小,調(diào)用課程方法
    • jdk Calendar.getInstance()
  • 工廠方法模式(Fatory Method Pattern)
    • 課程為例 不同課程有不同職責(zé)(單一職責(zé)) ,java課程有javaFactory去創(chuàng)建,python課程有python Factory創(chuàng)建
    • logback
  • 抽象工廠模式(Abastract Factory Pattern)
    • 以課程為例剿配,課程添加了職責(zé)(多個(gè)職責(zé))呼胚,課程工廠提供多個(gè)職責(zé),java 產(chǎn)品線不同人做不同事,python 產(chǎn)品線不同人做不同事,

單例模式(Singleton Pattern)

餓漢式單例

  • 餓漢式單例是在類(lèi)加載的時(shí)候就立即初始化沪编,并且創(chuàng)建單例對(duì)象蚁廓。絕對(duì)線程安全厨幻,在線 程還沒(méi)出現(xiàn)以前就是實(shí)例化了况脆,不可能存在訪問(wèn)安全問(wèn)題

懶漢式單例

  • 被外部類(lèi)調(diào)用的時(shí)候內(nèi)部類(lèi)才會(huì)加載 (線程不安全)
    • synchronized
      • 單鎖 線程阻塞格了,效率不高
      • 雙重鎖 指令重排 volatile
      • 靜態(tài)內(nèi)部類(lèi)
  • 反射破壞單例
    //史上最牛 B 的單例模式的實(shí)現(xiàn)方式 
    public class LazyInnerClassSingleton { 
        //默認(rèn)使用 LazyInnerClassGeneral 的時(shí)候,會(huì)先初始化內(nèi)部類(lèi) 
        // 如果沒(méi)使用的話性湿,內(nèi)部類(lèi)是不加載的 
        //TODO 防止反射破壞單例
        private LazyInnerClassSingleton() {
            if (LazyHolder.LAZY != null) {
                throw new RuntimeException("不允許創(chuàng)建多個(gè)實(shí)例");
            }
        }
        //每一個(gè)關(guān)鍵字都不是多余的 
        // static 是為了使單例的空間共享 
        // 保證這個(gè)方法不會(huì)被重寫(xiě)肤频,重載 
         public static final LazyInnerClassSingleton getInstance(){ 
            //在返回結(jié)果以前算墨,一定會(huì)先加載內(nèi)部類(lèi) 
             return LazyHolder.LAZY; 
             
        }
        //默認(rèn)不加載 
        private static class LazyHolder{ 
            private static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton(); 
        }

    }
  • 序列化破壞單例
    • readResolve() 方法

注冊(cè)式單例

  • 枚舉登記
  • 容器緩存

ThreadLocal 線程單例

  • ThreadLocal 不能保證其 創(chuàng)建的對(duì)象是全局唯一净嘀,但是能保證在單個(gè)線程中是唯一的挖藏,天生的線程安全

原型模式

簡(jiǎn)單克隆

  • 只是完整 復(fù)制了值類(lèi)型數(shù)據(jù),沒(méi)有賦值引用對(duì)象

深度克隆

  • 引用的對(duì)象也克隆了
    • 引用對(duì)象也clone() ;
      • 缺點(diǎn):使用Clone方法實(shí)現(xiàn)深復(fù)制存在的缺點(diǎn): 存在多個(gè)引用的成員變量岩臣,將做多次處理架谎。
    • 序列化/反序列化,代碼如下:
     public Object deepCopy() throws Exception {
        //將對(duì)象寫(xiě)入流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        //從流中讀取對(duì)象
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }
    1)在Java語(yǔ)言里深克隆一個(gè)對(duì)象谷扣,常常可以先使對(duì)象實(shí)現(xiàn)Serializable接口裹匙,然后把對(duì)象(實(shí)際上只是對(duì)象的一個(gè)拷貝)寫(xiě)到一個(gè)流里,再?gòu)牧骼镒x出來(lái)蛔溃,便可以重建對(duì)象篱蝇。
    2)這樣做的前提示對(duì)象以及對(duì)象內(nèi)部所有引用到的對(duì)象都是可串行化的零截,否則,就需要仔細(xì)考察那些不可串行化的對(duì)象是否設(shè)成transient哪工,從而將之排除在復(fù)制過(guò)程之外雁比。
    
    //TODO 
    六撤嫩、關(guān)于實(shí)現(xiàn)Seriallizable接口的類(lèi)中的serialVersionUID問(wèn)題
    
    如果你的對(duì)象序列化后存在硬盤(pán)上面后序攘,可是后來(lái)你更改了類(lèi)的field(增加或減少或改名),當(dāng)你反序列化時(shí)丈牢,就會(huì)出現(xiàn)Execption的娩怎,這樣就會(huì)造成不兼容性的問(wèn)題泛粹。
    
    但當(dāng)serialVersionUID相同時(shí)晶姊,它就會(huì)將不一樣的field以type的缺省值Deserialize,這樣可以避開(kāi)不兼容的問(wèn)題钾怔。
    

克隆破壞單例

  • 要么你我們的單例類(lèi)不實(shí)現(xiàn) Cloneable 接口蒙挑;要么我們重寫(xiě) clone()方法忆蚀,在 clone 方法中返回單例對(duì)象即可馋袜,具體 代碼如下:
@Override 
protected Object clone() throws CloneNotSupportedException { 
    return INSTANCE;
}

代理模式

靜態(tài)代理

  • 王爸給小王相親, 相親過(guò)程中,王爸就是小王的代理(類(lèi)王爸中有小王類(lèi)[ 有個(gè)相親方法],王爸類(lèi)中有方法去調(diào)用成員變量小王類(lèi)的相親方法)
  • 業(yè)務(wù)舉例,訂單業(yè)務(wù)擴(kuò)容,分庫(kù)分表, 創(chuàng)建數(shù)據(jù)庫(kù)路由類(lèi)(數(shù)據(jù)源等),靜態(tài)代理類(lèi), StaticProxy( ? implements InterFace)

動(dòng)態(tài)代理

jdk代理

  • 反射獲取

CGLib代理

  • FastClass 機(jī) 制
  • FastClass 并不是跟代理類(lèi)一塊生成的察皇,而是在第一次執(zhí)行 MethodProxy -->invoke/invokeSuper 時(shí)生成的并放在了緩存中

CGLib 和 JDK 動(dòng)態(tài)代理對(duì)比

  1. JDK 動(dòng)態(tài)代理是實(shí)現(xiàn)了被代理對(duì)象的==接口==什荣,CGLib 是繼承了被代理對(duì)象溃睹。
  2. JDK 和 CGLib 都是在運(yùn)行期生成字節(jié)碼胰坟,JDK 是直接寫(xiě) Class 字節(jié)碼,CGLib 使用 ASM 框架寫(xiě) Class 字節(jié)碼笔横,Cglib 代理實(shí)現(xiàn)更復(fù)雜竞滓,生成代理類(lèi)比 JDK 效率低。
  3. JDK 調(diào)用代理方法吹缔,是通過(guò)反射機(jī)制調(diào)用商佑,CGLib 是通過(guò) FastClass 機(jī)制直接調(diào)用方法, CGLib 執(zhí)行效率更高厢塘。

委派模式

  • 老板(Boss)給項(xiàng)目經(jīng)理(Leader)下達(dá)任務(wù)茶没,項(xiàng)目經(jīng)理會(huì)根據(jù) 實(shí)際情況給每個(gè)員工派發(fā)工作任務(wù)肌幽,待員工把工作任務(wù)完成之后,再由項(xiàng)目經(jīng)理匯報(bào)工 作進(jìn)度和結(jié)果給老板

策略模式

  • 極客時(shí)間打折 ①.滿減 ②.新課邀請(qǐng)減③ 拼團(tuán)
  • 美團(tuán)外賣(mài)選擇支付方式 ①.美團(tuán)支付 ②.支付寶支付③ 微信支付 ④銀聯(lián)支付等等

模板模式

  • 入職流程:填寫(xiě)入職登記表-->打印簡(jiǎn)歷-->復(fù)印學(xué)歷-->復(fù)印身份證-->簽訂 勞動(dòng)合同-->建立花名冊(cè)-->辦理工牌-->安排工位等
  • 炒菜:洗鍋 -->點(diǎn)火-->熱鍋-->上油-->下原料-->翻炒-->放調(diào)料-->出鍋

適配器模式

  • xx網(wǎng)站登錄 ①.注冊(cè)登錄 ②. 微信.③ 手機(jī)號(hào) 等等
public class LoginForWechatAdapter implements LoginAdapter {
    public boolean support(Object adapter) { 
        return adapter instanceof LoginForWechatAdapter; 
        
    }
    public ResultMsg login(String id, Object adapter) { 
        sout(  WechatAdapter 登錄  ... );
    } 
}

裝飾者模式

  • 如給煎餅加雞蛋喂急;給蛋糕加上一些水果;給房子 裝修等

觀察者模式

  • 微信通知 Observer\Observable Event com.google.guava @Subscribe

單例模式和工廠模式

  • 實(shí)際業(yè)務(wù)代碼中笛求,通常會(huì)把工廠類(lèi)設(shè)計(jì)為單例

策略模式和工廠模式

  1. 工廠模式包含工廠方法模式和抽象工廠模式是創(chuàng)建型模式廊移,策略模式屬于行為型模 式。
  2. 工廠模式主要目的是封裝好創(chuàng)建邏輯探入,策略模式接收工廠創(chuàng)建好的對(duì)象狡孔,從而實(shí)現(xiàn)不 同的行為。

策略模式和委派模式

  1. 策略模式是委派模式內(nèi)部的一種實(shí)現(xiàn)形式蜂嗽,策略模式關(guān)注的結(jié)果是否能相互替代苗膝。
  2. 委派模式更關(guān)注分發(fā)和調(diào)度的過(guò)程。

模版方法和工廠方法模式

  1. 模板方法和策略模式都有封裝算法植旧。
  2. 策略模式是使不同算法可以相互替換辱揭,且不影響客戶端應(yīng)用層的使用。
  3. 模板方法是針對(duì)定義一個(gè)算法的流程隆嗅,將一些有細(xì)微差異的部分交給子類(lèi)實(shí)現(xiàn)界阁。
  4. 模板方法模式不能改變算法流程侯繁,策略模式可以改變算法流程且可替換胖喳。策略模式通 常用來(lái)代替 if...else...等條件分支語(yǔ)句

模版方法和策略模式

  1. 裝飾者模式關(guān)注點(diǎn)在于給對(duì)象動(dòng)態(tài)添加方法,而代理更加注重控制對(duì)對(duì)象的訪問(wèn)贮竟。
  2. 代理模式通常會(huì)在代理類(lèi)中創(chuàng)建被代理對(duì)象的實(shí)例丽焊,而裝飾者模式通常把被裝飾者作 為構(gòu)造參數(shù)。

裝飾者模式和靜態(tài)代理模式

  1. 裝飾者模式和適配器模式都是屬于包裝器模式(Wrapper Pattern)咕别。
  2. 裝飾者模式可以實(shí)現(xiàn)被裝飾者與相同的接口或者繼承被裝飾者作為它的子類(lèi)技健,而適配 器和被適配者可以實(shí)現(xiàn)不同的接口。

spring aop Execution 表達(dá)式

  • execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
modifiers-pattern:方法的操作權(quán)限
ret-type-pattern:返回值【必填】
declaring-type-pattern:方法所在的包
name-pattern:方法名 【必填】
parm-pattern:參數(shù)名 
throws-pattern:異常
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末惰拱,一起剝皮案震驚了整個(gè)濱河市雌贱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌偿短,老刑警劉巖欣孤,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異昔逗,居然都是意外死亡降传,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)勾怒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)婆排,“玉大人声旺,你說(shuō)我怎么就攤上這事《沃唬” “怎么了腮猖?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)翼悴。 經(jīng)常有香客問(wèn)我缚够,道長(zhǎng),這世上最難降的妖魔是什么鹦赎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任谍椅,我火速辦了婚禮,結(jié)果婚禮上古话,老公的妹妹穿的比我還像新娘雏吭。我一直安慰自己,他們只是感情好陪踩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布杖们。 她就那樣靜靜地躺著,像睡著了一般肩狂。 火紅的嫁衣襯著肌膚如雪摘完。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天傻谁,我揣著相機(jī)與錄音孝治,去河邊找鬼。 笑死审磁,一個(gè)胖子當(dāng)著我的面吹牛谈飒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播态蒂,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼杭措,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了钾恢?” 一聲冷哼從身側(cè)響起手素,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瘩蚪,沒(méi)想到半個(gè)月后泉懦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡募舟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年祠斧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拱礁。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡琢锋,死狀恐怖辕漂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吴超,我是刑警寧澤钉嘹,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站鲸阻,受9級(jí)特大地震影響跋涣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鸟悴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一陈辱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧细诸,春花似錦沛贪、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至猩系,卻和暖如春媚送,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寇甸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工塘偎, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人幽纷。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓式塌,卻偏偏與公主長(zhǎng)得像博敬,于是被迫代替她去往敵國(guó)和親友浸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容