設(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();
}
}
注冊(cè)式單例
ThreadLocal 線程單例
- ThreadLocal 不能保證其 創(chuàng)建的對(duì)象是全局唯一净嘀,但是能保證在單個(gè)線程中是唯一的挖藏,天生的線程安全
原型模式
簡(jiǎn)單克隆
- 只是完整 復(fù)制了值類(lèi)型數(shù)據(jù),沒(méi)有賦值引用對(duì)象
深度克隆
克隆破壞單例
- 要么你我們的單例類(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ì)比
- JDK 動(dòng)態(tài)代理是實(shí)現(xiàn)了被代理對(duì)象的==接口==什荣,CGLib 是繼承了被代理對(duì)象溃睹。
- JDK 和 CGLib 都是在運(yùn)行期生成字節(jié)碼胰坟,JDK 是直接寫(xiě) Class 字節(jié)碼,CGLib 使用 ASM 框架寫(xiě) Class 字節(jié)碼笔横,Cglib 代理實(shí)現(xiàn)更復(fù)雜竞滓,生成代理類(lèi)比 JDK 效率低。
- 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ì)為單例
策略模式和工廠模式
- 工廠模式包含工廠方法模式和抽象工廠模式是創(chuàng)建型模式廊移,策略模式屬于行為型模 式。
- 工廠模式主要目的是封裝好創(chuàng)建邏輯探入,策略模式接收工廠創(chuàng)建好的對(duì)象狡孔,從而實(shí)現(xiàn)不 同的行為。
策略模式和委派模式
- 策略模式是委派模式內(nèi)部的一種實(shí)現(xiàn)形式蜂嗽,策略模式關(guān)注的結(jié)果是否能相互替代苗膝。
- 委派模式更關(guān)注分發(fā)和調(diào)度的過(guò)程。
模版方法和工廠方法模式
- 模板方法和策略模式都有封裝算法植旧。
- 策略模式是使不同算法可以相互替換辱揭,且不影響客戶端應(yīng)用層的使用。
- 模板方法是針對(duì)定義一個(gè)算法的流程隆嗅,將一些有細(xì)微差異的部分交給子類(lèi)實(shí)現(xiàn)界阁。
- 模板方法模式不能改變算法流程侯繁,策略模式可以改變算法流程且可替換胖喳。策略模式通 常用來(lái)代替 if...else...等條件分支語(yǔ)句
模版方法和策略模式
- 裝飾者模式關(guān)注點(diǎn)在于給對(duì)象動(dòng)態(tài)添加方法,而代理更加注重控制對(duì)對(duì)象的訪問(wèn)贮竟。
- 代理模式通常會(huì)在代理類(lèi)中創(chuàng)建被代理對(duì)象的實(shí)例丽焊,而裝飾者模式通常把被裝飾者作 為構(gòu)造參數(shù)。
裝飾者模式和靜態(tài)代理模式
- 裝飾者模式和適配器模式都是屬于包裝器模式(Wrapper Pattern)咕别。
- 裝飾者模式可以實(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:異常