成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

我的Java設(shè)計(jì)模式-模板方法模式

levius / 2376人閱讀

摘要:模板方法模式定義定義抽象類并且聲明一些抽象基本方法供子類實(shí)現(xiàn)不同邏輯,同時(shí)在抽象類中定義具體方法把抽象基本方法封裝起來(lái),這就是模板方法模式。

近日,ofo小黃車宣布入駐法國(guó)巴黎,正式進(jìn)入全球第20個(gè)國(guó)家,共享單車已然改變了我們的出行方式。就拿我自己來(lái)說(shuō),每當(dāng)下班出地鐵的第一件事,以光速鎖定一輛共享單車,百米沖刺的速度搶在別人之前占領(lǐng)它。

而大家都是重復(fù)著同樣的動(dòng)作,拿出手機(jī)開(kāi)鎖、騎車、上鎖、結(jié)算,哇~這是何等壯觀的場(chǎng)景,甚至還有的不用開(kāi)鎖直接把車騎走的,鎖壞了嘛。

為什么要用模板方法模式

現(xiàn)在共享單車以開(kāi)鎖的方式來(lái)分,一般有掃碼開(kāi)鎖和密碼開(kāi)鎖兩種,來(lái)看共享單車使用流程的實(shí)現(xiàn)。

正常的思維邏輯是,抽象一個(gè)父類,子類繼承父類并實(shí)現(xiàn)父類方法。OK,看抽象類代碼:

public abstract class AbstractClass {

// 開(kāi)鎖
public abstract void unlock();
// 騎行
public abstract void ride();
// 上鎖
public abstract void lock();
// 結(jié)算
public abstract void pay();
// 用戶使用
public abstract void use();

}
抽象類定義了我們使用共享單車的幾個(gè)基本流程,現(xiàn)在有兩種不同開(kāi)鎖方式單車的使用,都繼承抽象類,代碼如下:

//
public class ScanBicycle extends AbstractClass {

@Override
public void unlock() {
    System.out.println("掃碼開(kāi)鎖");
}

@Override
public void ride() {
    System.out.println("騎起來(lái)很拉風(fēng)");
}

@Override
public void lock() {
    System.out.println("上鎖");
}

@Override
public void pay() {
    System.out.println("結(jié)算");
}

@Override
public void use() {
    unlock();
    ride();
    lock();
    pay();
}

}
以上是通過(guò)掃碼方式開(kāi)鎖騎行,再來(lái)看密碼開(kāi)鎖騎行,代碼如下:

public class CodeBicycle extends AbstractClass {

@Override
public void unlock() {
    System.out.println("密碼開(kāi)鎖");
}

@Override
public void ride() {
    System.out.println("騎起來(lái)很拉風(fēng)");
}

@Override
public void lock() {
    System.out.println("上鎖");
}

@Override
public void pay() {
    System.out.println("結(jié)算");
}

@Override
public void use() {
    unlock();
    ride();
    lock();
    pay();
}

}
好了,兩種方式都定義好了,看客戶端的調(diào)用:

public class Client {

public static void main(String[] args) {
    ScanBicycle scanBicycle = new ScanBicycle();
    scanBicycle.use();
    System.out.println("========================");
    CodeBicycle codeBicycle = new CodeBicycle();
    codeBicycle.use();
}

}
結(jié)果如下:

掃碼開(kāi)鎖
騎起來(lái)很拉風(fēng)
上鎖

結(jié)算

掃碼開(kāi)鎖
騎起來(lái)很拉風(fēng)
上鎖
結(jié)算
相信都已經(jīng)看出代碼的問(wèn)題,use方法的實(shí)現(xiàn)是一樣的,也就是代碼重復(fù)了,這是病必須得治,藥方就是模板方式模式。

模板方法模式

定義

??定義抽象類并且聲明一些抽象基本方法供子類實(shí)現(xiàn)不同邏輯,同時(shí)在抽象類中定義具體方法把抽象基本方法封裝起來(lái),這就是模板方法模式。

UML

模板方法模式
模板方法模式涉及到的角色有兩個(gè)角色:

抽象模板角色:定義一組基本方法供子類實(shí)現(xiàn),定義并實(shí)現(xiàn)組合了基本方法的模板方法。

具體模板角色:實(shí)現(xiàn)抽象模板角色定義的基本方法

模板方法模式還涉及到以下方法的概念:

基本方法

抽象方法:由抽象模板角色聲明,abstract修飾,具體模板角色實(shí)現(xiàn)。

鉤子方法:由抽象模板角色聲明并實(shí)現(xiàn),具體模板角色可實(shí)現(xiàn)加以擴(kuò)展。

具體方法:由抽象模板角色聲明并實(shí)現(xiàn),而子類并不實(shí)現(xiàn)。

模板方法

抽象模板角色聲明并實(shí)現(xiàn),負(fù)責(zé)對(duì)基本方法的調(diào)度,一般以final修飾,不允許具體模板角色重寫(xiě)。模板方法一般也是一個(gè)具體方法。

模式實(shí)戰(zhàn)

利用模板方式模式對(duì)上面的代碼進(jìn)行重構(gòu),來(lái)看抽象模板角色,代碼如下:

public abstract class AbstractClass {

protected boolean isNeedUnlock = true;  // 默認(rèn)需要開(kāi)鎖

/**
 * 基本方法,子類需要實(shí)現(xiàn)
 */
protected abstract void unlock();

/**
 * 基本方法,子類需要實(shí)現(xiàn)
 */
protected abstract void ride();

/**
 * 鉤子方法,子類可實(shí)現(xiàn)
 *
 * @param isNeedUnlock
 */
protected void isNeedUnlock(boolean isNeedUnlock) {
    this.isNeedUnlock = isNeedUnlock;
}

/**
 * 模板方法,負(fù)責(zé)調(diào)度基本方法,子類不可實(shí)現(xiàn)
 */
public final void use() {
    if (isNeedUnlock) {
        unlock();
    } else {
        System.out.println("========鎖壞了,不用解鎖========");
    }
    ride();
}

}
抽象模板角色定義了unlock和ride兩個(gè)使用單車的基本方法,還有一個(gè)鉤子方法,用來(lái)控制模板方法邏輯順序,核心是use模板方法,用final修飾,該方法完成對(duì)基本方法調(diào)度。注意,模板方法中對(duì)基本方法的調(diào)度是有順序有規(guī)則的。還有一點(diǎn),基本方法都是protected修飾的,因?yàn)榛痉椒ǘ际窃谝詐ublic修飾的模板方法中調(diào)用,并且可以由子類實(shí)現(xiàn),并不需要暴露給其他類調(diào)用。

現(xiàn)在來(lái)看兩個(gè)具體模板角色的實(shí)現(xiàn):

// 掃碼開(kāi)鎖的單車
public class ScanBicycle extends AbstractClass {

@Override
protected void unlock() {
    System.out.println("========" + "掃碼開(kāi)鎖" + "========");
}

@Override
protected void ride() {
    System.out.println(getClass().getSimpleName() + "騎起來(lái)很拉風(fēng)");
}

protected void isNeedUnlock(boolean isNeedUnlock) {
    this.isNeedUnlock = isNeedUnlock;
}

}

// 密碼開(kāi)鎖的單車
public class CodeBicycle extends AbstractClass {

@Override
protected void unlock() {
    System.out.println("========" + "密碼開(kāi)鎖" + "========");
}

@Override
protected void ride() {
    System.out.println(getClass().getSimpleName() + "騎起來(lái)很拉風(fēng)");
}

protected void isNeedUnlock(boolean isNeedUnlock) {
    this.isNeedUnlock = isNeedUnlock;
}

}
可以看到,相比之前的實(shí)現(xiàn),現(xiàn)在兩個(gè)具體類都不需要實(shí)現(xiàn)use方法,只負(fù)責(zé)實(shí)現(xiàn)基本方法的邏輯,職責(zé)上變得更加清晰了。來(lái)看用戶如何使用:

public class Client {

public static void main(String[] args) {
    ScanBicycle scanBicycle = new ScanBicycle();
    scanBicycle.use();
    
    CodeBicycle codeBicycle = new CodeBicycle();
    codeBicycle.use();
}

}
運(yùn)行結(jié)果如下:

========掃碼開(kāi)鎖========
ScanBicycle騎起來(lái)很拉風(fēng)
========密碼開(kāi)鎖========
CodeBicycle騎起來(lái)很拉風(fēng)
當(dāng)我以百米沖刺的速度跑到共享單車面前時(shí),發(fā)現(xiàn)這輛車的鎖是壞掉的,也就是不用開(kāi)鎖,免費(fèi)的,騎回家收藏也沒(méi)問(wèn)題。在代碼中只要調(diào)用鉤子方法isNeedUnlock就好,實(shí)現(xiàn)如下:

public class Client {

public static void main(String[] args) {
    ScanBicycle scanBicycle = new ScanBicycle();
    scanBicycle.isNeedUnlock(false);
    scanBicycle.use();

    CodeBicycle codeBicycle = new CodeBicycle();
    codeBicycle.isNeedUnlock(true);
    codeBicycle.use();
}

}
運(yùn)行結(jié)果如下:

========鎖壞了,不用解鎖========
ScanBicycle騎起來(lái)很拉風(fēng)
========密碼開(kāi)鎖========
CodeBicycle騎起來(lái)很拉風(fēng)
上面提到模板方法對(duì)基本方法的調(diào)度是有順序的,也就是說(shuō)模板方法中的邏輯是不可變的,子類只實(shí)現(xiàn)可以被實(shí)現(xiàn)的基本方法,但不會(huì)改變模板方法中的頂級(jí)邏輯。而鉤子方法的使用只是對(duì)模板方法中邏輯的控制,影響的是模板方法的結(jié)果,并不會(huì)改變?cè)羞壿嫛?/p>

模板方法模式的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

1)良好的封裝性。把公有的不變的方法封裝在父類,而子類負(fù)責(zé)實(shí)現(xiàn)具體邏輯。

2)良好的擴(kuò)展性:增加功能由子類實(shí)現(xiàn)基本方法擴(kuò)展,符合單一職責(zé)原則和開(kāi)閉原則。

3)復(fù)用代碼。

缺點(diǎn)

1)由于是通過(guò)繼承實(shí)現(xiàn)代碼復(fù)用來(lái)改變算法,靈活度會(huì)降低。

2)子類的執(zhí)行影響父類的結(jié)果,增加代碼閱讀難度。

總結(jié)

模板方法模式看上去簡(jiǎn)單,但是整個(gè)模式涉及到的都是面向?qū)ο笤O(shè)計(jì)的核心,比如繼承封裝,基于繼承的代碼復(fù)用,方法的實(shí)現(xiàn)等等。當(dāng)中還有涉及到一些關(guān)鍵詞的使用,也是我們Java編程中需要掌握的基礎(chǔ)。總體來(lái)說(shuō),模板方法模式是很好的學(xué)習(xí)對(duì)象。下一篇是中介者模式,您的點(diǎn)贊和關(guān)注是我的動(dòng)力,再會(huì)!

更多精彩干貨關(guān)注“AndroidJet的開(kāi)發(fā)之路”公眾號(hào)

設(shè)計(jì)模式Java源碼GitHub下載:https://github.com/jetLee92/D...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/68265.html

相關(guān)文章

  • 我的Java設(shè)計(jì)模式-責(zé)任鏈模式

    摘要:咦這一層一層上報(bào)就涉及到這次的責(zé)任鏈模式。責(zé)任鏈模式和觀察者模式存在一個(gè)共同點(diǎn),就是傳遞責(zé)任鏈模式是一級(jí)一級(jí)的傳遞,形成一條鏈,鏈節(jié)點(diǎn)處理者之間是存在傳遞關(guān)系的。這是責(zé)任鏈模式和觀察者模式的區(qū)別,也是責(zé)任鏈模式的核心。 今天來(lái)說(shuō)說(shuō)程序員小猿和產(chǎn)品就關(guān)于需求發(fā)生的故事。前不久,小猿收到了產(chǎn)品的需求。 產(chǎn)品經(jīng)理:小猿,為了迎合大眾屌絲用戶的口味,我們要放一張圖,要露點(diǎn)的。 小猿:........

    douzifly 評(píng)論0 收藏0
  • 假如時(shí)光倒流,我會(huì)這么學(xué)習(xí)Java

    摘要:看起來(lái)沒(méi)有集合框架,線程,等那么耀眼,但它可是很多框架的基礎(chǔ)啊回復(fù)反射查看相關(guān)文章,先把基礎(chǔ)學(xué)會(huì),后面的得用到它。 回頭看看, 我進(jìn)入Java 領(lǐng)域已經(jīng)快15個(gè)年頭了, 雖然學(xué)的也一般, 但是分享下我的心得,估計(jì)也能幫大家少走點(diǎn)彎路。[入門]我在2001年之前是C/C++陣營(yíng), 有C和面向?qū)ο蟮幕A(chǔ), 后來(lái)轉(zhuǎn)到Java ,發(fā)現(xiàn)沒(méi)有指針的Java真是好簡(jiǎn)單, 另外Java 的類庫(kù)好用的讓...

    bladefury 評(píng)論0 收藏0
  • 面試官:“談?wù)凷pring中都用到了那些設(shè)計(jì)模式?”。

    摘要:會(huì)一直完善下去,歡迎建議和指導(dǎo),同時(shí)也歡迎中用到了那些設(shè)計(jì)模式中用到了那些設(shè)計(jì)模式這兩個(gè)問(wèn)題,在面試中比較常見(jiàn)。工廠設(shè)計(jì)模式使用工廠模式可以通過(guò)或創(chuàng)建對(duì)象。 我自己總結(jié)的Java學(xué)習(xí)的系統(tǒng)知識(shí)點(diǎn)以及面試問(wèn)題,已經(jīng)開(kāi)源,目前已經(jīng) 41k+ Star。會(huì)一直完善下去,歡迎建議和指導(dǎo),同時(shí)也歡迎Star: https://github.com/Snailclimb... JDK 中用到了那...

    Astrian 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<