Java高頻面試集-基礎(chǔ)-設(shè)計(jì)模式

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

目前來(lái)說(shuō)最好理解的博客:
http://www.itdecent.cn/p/61b67ca754a3

1、單例模式

1.1、惡漢

//類(lèi)創(chuàng)建就加載
public class Singleton{
    private static Singleton instance = new Singleton();
    
    public static Singleton getInstance(){
        return instance ;
    }

1.1、懶漢

//需要用的時(shí)候才創(chuàng)建
public class Singleton02{
    private static Singleton02 instance;
    public static Singleton02 getInstance(){
        if (instance == null){
            synchronized (Singleton02.class){
                if (instance == null){
                    instance = new Singleton02();
                }
            }
        }
        return instance;
    }
}

2、工廠模式

2.1、簡(jiǎn)單工廠

定義:簡(jiǎn)單地說(shuō),簡(jiǎn)單工廠模式通常就是這樣,一個(gè)工廠類(lèi) XxxFactory,里面有一個(gè)靜態(tài)方法,根據(jù)我們不同的參數(shù),返回不同的派生自同一個(gè)父類(lèi)(或?qū)崿F(xiàn)同一接口)的實(shí)例對(duì)象。

public class FoodFactory {

    public static Food makeFood(String name) {
        if (name.equals("noodle")) {
            Food noodle = new LanZhouNoodle();
            noodle.addSpicy("more");
            return noodle;
        } else if (name.equals("chicken")) {
            Food chicken = new HuangMenChicken();
            chicken.addCondiment("potato");
            return chicken;
        } else {
            return null;
        }
    }
}

2.2、工廠方法

定義:核心在于,我們需要在第一步選好我們需要的工廠。
第一步,我們需要選取合適的工廠,然后第二步基本上和簡(jiǎn)單工廠一樣。

public interface FoodFactory {
    Food makeFood(String name);
}
public class ChineseFoodFactory implements FoodFactory {

    @Override
    public Food makeFood(String name) {
        if (name.equals("A")) {
            return new ChineseFoodA();
        } else if (name.equals("B")) {
            return new ChineseFoodB();
        } else {
            return null;
        }
    }
}
public class AmericanFoodFactory implements FoodFactory {

    @Override
    public Food makeFood(String name) {
        if (name.equals("A")) {
            return new AmericanFoodA();
        } else if (name.equals("B")) {
            return new AmericanFoodB();
        } else {
            return null;
        }
    }
}
// 客戶(hù)端調(diào)用
public class APP {
    public static void main(String[] args) {
        // 先選擇一個(gè)具體的工廠
        FoodFactory factory = new ChineseFoodFactory();
        // 由第一步的工廠產(chǎn)生具體的對(duì)象,不同的工廠造出不一樣的對(duì)象
        Food food = factory.makeFood("A");
    }
}

2.3、抽象工廠

定義:當(dāng)涉及到產(chǎn)品族的時(shí)候,就需要引入抽象工廠模式了。

一個(gè)經(jīng)典的例子是造一臺(tái)電腦。我們先不引入抽象工廠模式,看看怎么實(shí)現(xiàn)。

因?yàn)殡娔X是由許多的構(gòu)件組成的,我們將 CPU 和主板進(jìn)行抽象,然后 CPU 由 CPUFactory 生產(chǎn),主板由 MainBoardFactory 生產(chǎn),然后,我們?cè)賹?CPU 和主板搭配起來(lái)組合在一起,如下圖:


QQ20191025-135454.png

這個(gè)時(shí)候的客戶(hù)端調(diào)用是這樣的:

// 得到 Intel 的 CPU
CPUFactory cpuFactory = new IntelCPUFactory();
CPU cpu = intelCPUFactory.makeCPU();

// 得到 AMD 的主板
MainBoardFactory mainBoardFactory = new AmdMainBoardFactory();
MainBoard mainBoard = mainBoardFactory.make();

// 組裝 CPU 和主板
Computer computer = new Computer(cpu, mainBoard);

單獨(dú)看 CPU 工廠和主板工廠,它們分別是前面我們說(shuō)的工廠模式。這種方式也容易擴(kuò)展,因?yàn)橐o電腦加硬盤(pán)的話(huà),只需要加一個(gè) HardDiskFactory 和相應(yīng)的實(shí)現(xiàn)即可,不需要修改現(xiàn)有的工廠。但是,這種方式有一個(gè)問(wèn)題,那就是如果 Intel 家產(chǎn)的 CPU 和 AMD 產(chǎn)的主板不能兼容使用,那么這代碼就容易出錯(cuò),因?yàn)榭蛻?hù)端并不知道它們不兼容,也就會(huì)錯(cuò)誤地出現(xiàn)隨意組合。

下面就是我們要說(shuō)的產(chǎn)品族的概念,它代表了組成某個(gè)產(chǎn)品的一系列附件的集合:


QQ20191025-135712.png

當(dāng)涉及到這種產(chǎn)品族的問(wèn)題的時(shí)候,就需要抽象工廠模式來(lái)支持了。我們不再定義 CPU 工廠、主板工廠、硬盤(pán)工廠、顯示屏工廠等等,我們直接定義電腦工廠,每個(gè)電腦工廠負(fù)責(zé)生產(chǎn)所有的設(shè)備,這樣能保證肯定不存在兼容問(wèn)題。

QQ20191025-135739.png

這個(gè)時(shí)候,對(duì)于客戶(hù)端來(lái)說(shuō),不再需要單獨(dú)挑選 CPU廠商、主板廠商、硬盤(pán)廠商等,直接選擇一家品牌工廠,品牌工廠會(huì)負(fù)責(zé)生產(chǎn)所有的東西,而且能保證肯定是兼容可用的。

public static void main(String[] args) {
    // 第一步就要選定一個(gè)“大廠”
    ComputerFactory cf = new AmdFactory();
    // 從這個(gè)大廠造 CPU
    CPU cpu = cf.makeCPU();
    // 從這個(gè)大廠造主板
    MainBoard board = cf.makeMainBoard();
      // 從這個(gè)大廠造硬盤(pán)
      HardDisk hardDisk = cf.makeHardDisk();

    // 將同一個(gè)廠子出來(lái)的 CPU、主板、硬盤(pán)組裝在一起
    Computer result = new Computer(cpu, board, hardDisk);
}

當(dāng)然,抽象工廠的問(wèn)題也是顯而易見(jiàn)的,比如我們要加個(gè)顯示器,就需要修改所有的工廠,給所有的工廠都加上制造顯示器的方法。這有點(diǎn)違反了對(duì)修改關(guān)閉,對(duì)擴(kuò)展開(kāi)放這個(gè)設(shè)計(jì)原則。

3、策略模式

4、裝飾模式

裝飾者模式:若要擴(kuò)展功能,裝飾者提供了比集成更有彈性的替代方案,動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。

  • 1、裝備的超類(lèi):IEquip.java

    • 2、各個(gè)裝備的實(shí)現(xiàn)類(lèi):

    • eg:武器的實(shí)現(xiàn)類(lèi): ArmEquip.java* 3、裝飾品的超類(lèi)(裝飾品也屬于裝備):IEquipDecorator.java

    • 4、裝飾品的實(shí)現(xiàn)類(lèi):

    • eg:藍(lán)寶石的實(shí)現(xiàn)類(lèi)(可累加): BlueGemDecorator.java

  • 5、最后測(cè)試:計(jì)算攻擊力和查看描述:

Log.e("---", "一個(gè)鑲嵌2顆紅寶石,1顆藍(lán)寶石的靴子: ");
IEquip iEquip = new RedGemDecotator(new RedGemDecotator(new BlueGemDecotator(new ShoeEquip())));
Log.e("---", "攻擊力:" + iEquip.caculateAttack());
Log.e("---", "描述語(yǔ):" + iEquip.description());

5、代理模式

定義:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪(fǎng)問(wèn)。在某些情況下,一個(gè)客戶(hù)不想或者不能直接引用另一個(gè)對(duì)象,而代理對(duì)象可以在客戶(hù)端和目標(biāo)對(duì)象之間起到中介的作用。

比如:微商。一般都是廠家委托給代理商進(jìn)行銷(xiāo)售,顧客跟代理商打交道,而不直接與產(chǎn)品實(shí)際生產(chǎn)者進(jìn)行關(guān)聯(lián)。

6、建造者模式

7、觀察者模式

實(shí)際生活的例子:下面就以微信服務(wù)號(hào)為背景,給大家介紹觀察者模式。
Java開(kāi)發(fā)中的例子:RabbitMQ

20140420130751265.jpeg

如上圖所示,服務(wù)號(hào)就是我們的主題,使用者就是觀察者?,F(xiàn)在我們明確下功能:

  • 服務(wù)號(hào)就是主題,業(yè)務(wù)就是推送消息
  • 觀察者只需要訂閱主題,只要有新的消息就會(huì)送來(lái)
  • 當(dāng)不想要此主題消息時(shí),取消訂閱
  • 只要服務(wù)號(hào)還在,就可以一直有人訂閱

8、適配器模式

定義:將一個(gè)類(lèi)的接口轉(zhuǎn)換成客戶(hù)期望的另一個(gè)接口,適配器讓原本接口不兼容的類(lèi)可以相互合作。這個(gè)定義還好,說(shuō)適配器的功能就是把一個(gè)接口轉(zhuǎn)成另一個(gè)接口。

  • 以充電器為實(shí)例: 手機(jī)充電器一般都是5V左右吧,咱天朝的家用交流電壓220V,所以手機(jī)充電需要一個(gè)適配器(降壓器)
20140514213319921.jpeg
20140514213339734.jpeg

9、外觀模式

定義:提供一個(gè)統(tǒng)一的接口,用來(lái)訪(fǎng)問(wèn)子系統(tǒng)中的一群接口,外觀定義了一個(gè)高層的接口,讓子系統(tǒng)更容易使用。其實(shí)就是為了方便客戶(hù)的使用,把一群操作,封裝成一個(gè)方法。

工作中的例子:
APP的首頁(yè)需要讀取很多接口,如:廣告,商品,活動(dòng),分類(lèi)等等。使用外觀模式可以將所有的接口整合成一個(gè)接口,統(tǒng)一輸出。

參考
https://blog.csdn.net/lmj623565791/article/details/25837275

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 工廠模式 單體模式 模塊模式 代理模式 職責(zé)鏈模式 命令模式 模板方法模式 策略模式 發(fā)布-訂閱模式 中介者模式 ...
    HelloJames閱讀 1,078評(píng)論 0 6
  • 設(shè)計(jì)模式(Design pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過(guò)分類(lèi)編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。 Gi...
    Jinbeen閱讀 63,456評(píng)論 7 141
  • 很開(kāi)心19年的第一天去徒步,迎接了新的一天。很開(kāi)心和自己的校友一起玩。每次參加活動(dòng)都可以遇到很多朋友,有不同的見(jiàn)識(shí)...
    花兒的博文閱讀 493評(píng)論 0 0

友情鏈接更多精彩內(nèi)容