成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入理解工廠模式

zhou_you / 3052人閱讀

摘要:工廠模式的分類簡(jiǎn)單工廠模式,又稱靜態(tài)工廠方法模式。工廠方法模式,又稱多態(tài)性工廠模式或虛擬構(gòu)造子模式抽象工廠模式,又稱工具箱或模式。具體產(chǎn)品角色抽象工廠模式所創(chuàng)建的任何產(chǎn)品對(duì)象都是某一個(gè)具體產(chǎn)品類的實(shí)例。

Java面試通關(guān)手冊(cè)(Java學(xué)習(xí)指南,歡迎Star,會(huì)一直完善下去,歡迎建議和指導(dǎo)):https://github.com/Snailclimb/Java_Guide

歷史回顧:

深入理解單例模式

歷史文章推薦:

分布式系統(tǒng)的經(jīng)典基礎(chǔ)理論

可能是最漂亮的Spring事務(wù)管理詳解

面試中關(guān)于Java虛擬機(jī)(jvm)的問(wèn)題看這篇就夠了

[TOC]

一 工廠模式介紹 1.1 工廠模式的定義

先來(lái)看一下GOF為工廠模式的定義:

“Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.”(在基類中定義創(chuàng)建對(duì)象的一個(gè)接口,讓子類決定實(shí)例化哪個(gè)類。工廠方法讓一個(gè)類的實(shí)例化延遲到子類中進(jìn)行。)
1.2 工廠模式的分類:

(1)簡(jiǎn)單工廠(Simple Factory)模式,又稱靜態(tài)工廠方法模式(Static Factory Method Pattern)。

(2)工廠方法(Factory Method)模式,又稱多態(tài)性工廠(Polymorphic Factory)模式或虛擬構(gòu)造子(Virtual Constructor)模式;

(3)抽象工廠(Abstract Factory)模式,又稱工具箱(Kit 或Toolkit)模式。

1.3 在開(kāi)源框架中的使用

舉兩個(gè)比較常見(jiàn)的例子(我暫時(shí)可以準(zhǔn)確想到的,當(dāng)然還有很多很多):

(1)Spring中通過(guò)getBean("xxx")獲取Bean;

(2) Java消息服務(wù)JMS中(下面以消息隊(duì)列ActiveMQ為例子)

關(guān)于消息隊(duì)列ActiveMQ的使用可以查看:消息隊(duì)列ActiveMQ的使用詳解

        // 1、創(chuàng)建一個(gè)連接工廠對(duì)象,需要指定服務(wù)的ip及端口。
       ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.155:61616");
       // 2、使用工廠對(duì)象創(chuàng)建一個(gè)Connection對(duì)象。
       Connection connection = connectionFactory.createConnection();
1.4 為什么要用工廠模式

(1) 解耦 :把對(duì)象的創(chuàng)建和使用的過(guò)程分開(kāi)

(2)降低代碼重復(fù): 如果創(chuàng)建某個(gè)對(duì)象的過(guò)程都很復(fù)雜,需要一定的代碼量,而且很多地方都要用到,那么就會(huì)有很多的重復(fù)代碼。

(3) 降低維護(hù)成本 :由于創(chuàng)建過(guò)程都由工廠統(tǒng)一管理,所以發(fā)生業(yè)務(wù)邏輯變化,不需要找到所有需要?jiǎng)?chuàng)建對(duì)象B的地方去逐個(gè)修正,只需要在工廠里修改即可,降低維護(hù)成本。

關(guān)于工廠模式的作用,Mark一篇文章:https://blog.csdn.net/lovelion/article/details/7523392

二 簡(jiǎn)單工廠模式 2.1 介紹

嚴(yán)格的說(shuō),簡(jiǎn)單工廠模式并不是23種常用的設(shè)計(jì)模式之一,它只算工廠模式的一個(gè)特殊實(shí)現(xiàn)。簡(jiǎn)單工廠模式在實(shí)際中的應(yīng)用相對(duì)于其他2個(gè)工廠模式用的還是相對(duì)少得多,因?yàn)樗贿m應(yīng)很多簡(jiǎn)單的情況。

最重要的是它違背了我們?cè)诟攀鲋姓f(shuō)的 開(kāi)放-封閉原則 (雖然可以通過(guò)反射的機(jī)制來(lái)避免,后面我們會(huì)介紹到) 。因?yàn)槊看文阋绿砑右粋€(gè)功能,都需要在生switch-case 語(yǔ)句(或者if-else 語(yǔ)句)中去修改代碼,添加分支條件。

2.2 適用場(chǎng)景

(1)需要?jiǎng)?chuàng)建的對(duì)象較少。

(2)客戶端不關(guān)心對(duì)象的創(chuàng)建過(guò)程。

2.3 簡(jiǎn)單工廠模式角色分配:

工廠(Factory)角色 :簡(jiǎn)單工廠模式的核心,它負(fù)責(zé)實(shí)現(xiàn)創(chuàng)建所有實(shí)例的內(nèi)部邏輯。工廠類可以被外界直接調(diào)用,創(chuàng)建所需的產(chǎn)品對(duì)象。

抽象產(chǎn)品(Product)角色 :簡(jiǎn)單工廠模式所創(chuàng)建的所有對(duì)象的父類,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口。

具體產(chǎn)品(Concrete Product)角色:簡(jiǎn)單工廠模式的創(chuàng)建目標(biāo),所有創(chuàng)建的對(duì)象都是充當(dāng)這個(gè)角色的某個(gè)具體類的實(shí)例。

2.4 簡(jiǎn)單工廠實(shí)例

創(chuàng)建一個(gè)可以繪制不同形狀的繪圖工具,可以繪制圓形,正方形,三角形,每個(gè)圖形都會(huì)有一個(gè)draw()方法用于繪圖.

(1)創(chuàng)建Shape接口

public interface Shape {
    void draw();
}

(2)創(chuàng)建實(shí)現(xiàn)該接口的具體圖形類

圓形

public class Circle implements Shape {
    public Circle() {
        System.out.println("Circle");
    }
    @Override
    public void draw() {
        System.out.println("Draw Circle");
    }
}

長(zhǎng)方形

public class Rectangle implements Shape {
    public Rectangle() {
        System.out.println("Rectangle");
    }
    @Override
    public void draw() {
        System.out.println("Draw Rectangle");
    }
}

正方形

public class Square implements Shape {
    public Square() {
        System.out.println("Square");
    }

    @Override
    public void draw() {
        System.out.println("Draw Square");
    }
}

(3)創(chuàng)建工廠類:

public class ShapeFactory {

    // 使用 getShape 方法獲取形狀類型的對(duì)象
    public static Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        } else if (shapeType.equalsIgnoreCase("SQUARE")) {
            return new Square();
        }
        return null;
    }
}

(4)測(cè)試方法:

public class Test {

    public static void main(String[] args) {

        // 獲取 Circle 的對(duì)象,并調(diào)用它的 draw 方法
        Shape circle = ShapeFactory.getShape("CIRCLE");
        circle.draw();

        // 獲取 Rectangle 的對(duì)象,并調(diào)用它的 draw 方法
        Shape rectangle = ShapeFactory.getShape("RECTANGLE");
        rectangle.draw();

        // 獲取 Square 的對(duì)象,并調(diào)用它的 draw 方法
        Shape square = ShapeFactory.getShape("SQUARE");
        square.draw();
    }
}

輸出結(jié)果:

Circle
Draw Circle
Rectangle
Draw Rectangle
Square
Draw Square

這樣的實(shí)現(xiàn)有個(gè)問(wèn)題,如果我們新增產(chǎn)品類的話,就需要修改工廠類中的getShape()方法,這很明顯不符合 開(kāi)放-封閉原則 。

2.5 使用反射機(jī)制改善簡(jiǎn)單工廠

將工廠類改為下面的形式:

package factory_pattern;

/**
 * 利用反射解決簡(jiǎn)單工廠每次增加新了產(chǎn)品類都要修改產(chǎn)品工廠的弊端
 * 
 * @author Administrator
 *
 */
public class ShapeFactory2 {
    public static Object getClass(Class clazz) {
        Object obj = null;

        try {
            obj = Class.forName(clazz.getName()).newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return obj;
    }
}

測(cè)試方法:

package factory_pattern;

public class Test2 {
    public static void main(String[] args) {

        Circle circle = (Circle) ShapeFactory2.getClass(factory_pattern.Circle.class);
        circle.draw();

        Rectangle rectangle = (Rectangle) ShapeFactory2.getClass(factory_pattern.Rectangle.class);
        rectangle.draw();

        Square square = (Square) ShapeFactory2.getClass(factory_pattern.Square.class);
        square.draw();
    }

}

這種方式的雖然符合了 開(kāi)放-關(guān)閉原則 ,但是每一次傳入的都是產(chǎn)品類的全部路徑,這樣比較麻煩。如果需要改善的話可以通過(guò) 反射+配置文件 的形式來(lái)改善,這種方式使用的也是比較多的。

3 工廠方法模式 3.1 介紹

工廠方法模式應(yīng)該是在工廠模式家族中是用的最多模式,一般項(xiàng)目中存在最多的就是這個(gè)模式。

工廠方法模式是簡(jiǎn)單工廠的僅一步深化, 在工廠方法模式中,我們不再提供一個(gè)統(tǒng)一的工廠類來(lái)創(chuàng)建所有的對(duì)象,而是針對(duì)不同的對(duì)象提供不同的工廠。也就是說(shuō) 每個(gè)對(duì)象都有一個(gè)與之對(duì)應(yīng)的工廠 。

3.2 適用場(chǎng)景

一個(gè)類不知道它所需要的對(duì)象的類:在工廠方法模式中,客戶端不需要知道具體產(chǎn)品類的類名,只需要知道所對(duì)應(yīng)的工廠即可,具體的產(chǎn)品對(duì)象由具體工廠類創(chuàng)建;客戶端需要知道創(chuàng)建具體產(chǎn)品的工廠類。

一個(gè)類通過(guò)其子類來(lái)指定創(chuàng)建哪個(gè)對(duì)象:在工廠方法模式中,對(duì)于抽象工廠類只需要提供一個(gè)創(chuàng)建產(chǎn)品的接口,而由其子類來(lái)確定具體要?jiǎng)?chuàng)建的對(duì)象,利用面向?qū)ο蟮亩鄳B(tài)性和里氏

將創(chuàng)建對(duì)象的任務(wù)委托給多個(gè)工廠子類中的某一個(gè),客戶端在使用時(shí)可以無(wú)需關(guān)心是哪一個(gè)工廠子類創(chuàng)建產(chǎn)品子類,需要時(shí)再動(dòng)態(tài)指定,可將具體工廠類的類名存儲(chǔ)在配置文件或數(shù)據(jù)庫(kù)中。

3.3 工廠方法模式角色分配:

抽象工廠(Abstract Factory)角色:是工廠方法模式的核心,與應(yīng)用程序無(wú)關(guān)。任何在模式中創(chuàng)建的對(duì)象的工廠類必須實(shí)現(xiàn)這個(gè)接口。

具體工廠(Concrete Factory)角色 :這是實(shí)現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程序密切相關(guān)的邏輯,并且受到應(yīng)用程序調(diào)用以創(chuàng)建某一種產(chǎn)品對(duì)象。

抽象產(chǎn)品(AbstractProduct)角色 :工廠方法模式所創(chuàng)建的對(duì)象的超類型,也就是產(chǎn)品對(duì)象的共同父類或共同擁有的接口。

具體產(chǎn)品(Concrete Product)角色 :這個(gè)角色實(shí)現(xiàn)了抽象產(chǎn)品角色所定義的接口。某具體產(chǎn)品有專門的具體工廠創(chuàng)建,它們之間往往一一對(duì)應(yīng)

3.4 工廠方法模式實(shí)例

上面簡(jiǎn)單工廠例子中的圖形接口以及相關(guān)圖像實(shí)現(xiàn)類不變。我們只需要增加一個(gè)工廠接口以及實(shí)現(xiàn)這個(gè)接口的工廠類即可。

(1)增加一個(gè)工廠接口:

public interface Factory {
    public Shape getShape();
}

(2)增加相關(guān)工廠類:

圓形工廠類

public class CircleFactory implements Factory {

    @Override
    public Shape getShape() {
        // TODO Auto-generated method stub
        return new Circle();
    }

}

長(zhǎng)方形工廠類

public class RectangleFactory implements Factory{

    @Override
    public Shape getShape() {
        // TODO Auto-generated method stub
        return new Rectangle();
    }

}

圓形工廠類

public class SquareFactory implements Factory{

    @Override
    public Shape getShape() {
        // TODO Auto-generated method stub
        return new Square();
    }

}

(3)測(cè)試:

public class Test {

    public static void main(String[] args) {
        Factory circlefactory = new CircleFactory();
        Shape circle = circlefactory.getShape();
        circle.draw();
    }

}

輸出結(jié)果:

Circle
Draw Circle
4 抽象工廠模式 4.1 介紹

在工廠方法模式中,其實(shí)我們有一個(gè)潛在意識(shí)的意識(shí)。那就是我們生產(chǎn)的都是同一類產(chǎn)品。抽象工廠模式是工廠方法的僅一步深化,在這個(gè)模式中的工廠類不單單可以創(chuàng)建一種產(chǎn)品,而是可以創(chuàng)建一組產(chǎn)品。

抽象工廠應(yīng)該是比較最難理解的一個(gè)工廠模式了。

4.2 適用場(chǎng)景

和工廠方法一樣客戶端不需要知道它所創(chuàng)建的對(duì)象的類。

需要一組對(duì)象共同完成某種功能時(shí),并且可能存在多組對(duì)象完成不同功能的情況。(同屬于同一個(gè)產(chǎn)品族的產(chǎn)品)

系統(tǒng)結(jié)構(gòu)穩(wěn)定,不會(huì)頻繁的增加對(duì)象。(因?yàn)橐坏┰黾泳托枰薷脑写a,不符合開(kāi)閉原則)

4.3 抽象工廠方法模式角色分配:

抽象工廠(AbstractFactory)角色 :是工廠方法模式的核心,與應(yīng)用程序無(wú)關(guān)。任何在模式中創(chuàng)建的對(duì)象的工廠類必須實(shí)現(xiàn)這個(gè)接口。

具體工廠類(ConreteFactory)角色 :這是實(shí)現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程序密切相關(guān)的邏輯,并且受到應(yīng)用程序調(diào)用以創(chuàng)建某一種產(chǎn)品對(duì)象。

抽象產(chǎn)品(Abstract Product)角色 :工廠方法模式所創(chuàng)建的對(duì)象的超類型,也就是產(chǎn)品對(duì)象的共同父類或共同擁有的接口。

具體產(chǎn)品(Concrete Product)角色 :抽象工廠模式所創(chuàng)建的任何產(chǎn)品對(duì)象都是某一個(gè)具體產(chǎn)品類的實(shí)例。在抽象工廠中創(chuàng)建的產(chǎn)品屬于同一產(chǎn)品族,這不同于工廠模式中的工廠只創(chuàng)建單一產(chǎn)品,我后面也會(huì)詳解介紹到。

。

4.4 抽象工廠的工廠和工廠方法中的工廠有什么區(qū)別呢?

抽象工廠是生產(chǎn)一整套有產(chǎn)品的(至少要生產(chǎn)兩個(gè)產(chǎn)品),這些產(chǎn)品必須相互是有關(guān)系或有依賴的,而工廠方法中的工廠是生產(chǎn)單一產(chǎn)品的工廠。

4.5 抽象工廠模式實(shí)例

不知道大家玩過(guò)穿越火線或者吃雞這類游戲了嗎,游戲中存在各種槍。我們假設(shè)現(xiàn)在存在AK、M4A1兩類槍,每一種槍對(duì)應(yīng)一種子彈。我們現(xiàn)在這樣考慮生產(chǎn)AK的工廠可以順便生產(chǎn)AK使用的子彈,生產(chǎn)M4A1的工廠可以順便生產(chǎn)M4A1使用的子彈。(AK工廠生產(chǎn)AK系列產(chǎn)品包括子彈啊,AK槍的類型啊這些,M4A1工廠同理)

(1)創(chuàng)建相關(guān)接口:

public interface Gun {
    public void shooting();
}

子彈

public interface Bullet {
    public void load();
}

(2)創(chuàng)建接口對(duì)應(yīng)實(shí)現(xiàn)類:

AK類

public class AK implements Gun{

    @Override
    public void shooting() {
        System.out.println("shooting with AK");
        
    }

}

M4A1類

public class M4A1 implements Gun {

    @Override
    public void shooting() {
        System.out.println("shooting with M4A1");

    }

}

AK子彈類

public class AK_Bullet implements Bullet {

    @Override
    public void load() {
        System.out.println("Load bullets with AK");
    }

}

M4A1子彈類

public class M4A1
_Bullet implements Bullet {

    @Override
    public void load() {
        System.out.println("Load bullets with M4A1");
    }

}

(3)創(chuàng)建工廠接口

public interface Factory {
    public Gun produceGun();
    public Bullet produceBullet();
}

(4)創(chuàng)建具體工廠

生產(chǎn)AK和AK子彈的工廠

public class AK_Factory implements Factory{

    @Override
    public Gun produceGun() {
        return new AK();
    }

    @Override
    public Bullet produceBullet() {
        return new AK_Bullet();
    }

}

生產(chǎn)M4A1和M4A1子彈的工廠

public class M4A1_Factory implements Factory{

    @Override
    public Gun produceGun() {
        return new M4A1();
    }

    @Override
    public Bullet produceBullet() {
        return new M4A1_Bullet();
    }

}

(5)測(cè)試

public class Test {

    public static void main(String[] args) {  
        
     Factory factory;
     Gun gun;
     Bullet bullet;
     
     factory =new AK_Factory();
     bullet=factory.produceBullet();
     bullet.load();
     gun=factory.produceGun();
     gun.shooting(); 
     
    }

}

輸出結(jié)果:

Load bullets with AK
shooting with AK
我是Snailclimb,一個(gè)以架構(gòu)師為5年之內(nèi)目標(biāo)的小小白。 歡迎關(guān)注我的微信公眾號(hào):"Java面試通關(guān)手冊(cè)"(一個(gè)有溫度的微信公眾號(hào),期待與你共同進(jìn)步~~~堅(jiān)持原創(chuàng),分享美文,分享各種Java學(xué)習(xí)資源)

最后,就是使用阿里云服務(wù)器一段時(shí)間后,感覺(jué)阿里云真的很不錯(cuò),就申請(qǐng)做了阿里云大使,然后這是我的優(yōu)惠券地址.

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69537.html

相關(guān)文章

  • 深入理解控制反轉(zhuǎn)(IoC)和依賴注入(DI)

    摘要:本文一大半內(nèi)容都是通過(guò)舉例來(lái)讓讀者去理解什么是控制反轉(zhuǎn)和依賴注入,通過(guò)理解這些概念,來(lái)更加深入。這種由外部負(fù)責(zé)其依賴需求的行為,我們可以稱其為控制反轉(zhuǎn)。工廠模式,依賴轉(zhuǎn)移當(dāng)然,實(shí)現(xiàn)控制反轉(zhuǎn)的方法有幾種。 容器,字面上理解就是裝東西的東西。常見(jiàn)的變量、對(duì)象屬性等都可以算是容器。一個(gè)容器能夠裝什么,全部取決于你對(duì)該容器的定義。當(dāng)然,有這樣一種容器,它存放的不是文本、數(shù)值,而是對(duì)象、對(duì)象的描...

    HollisChuang 評(píng)論0 收藏0
  • 深入理解建造者模式 ——組裝復(fù)雜的實(shí)例

    摘要:而建造者模式則是要求按照指定的藍(lán)圖建造產(chǎn)品,它的主要目的是通過(guò)組裝零配件而產(chǎn)生一個(gè)新產(chǎn)品。最后通過(guò)一個(gè)套餐實(shí)例,介紹了建造者模式在實(shí)例中的基本使用手段。 歷史文章回顧: 設(shè)計(jì)模式專欄 深入理解單例模式 深入理解工廠模式 歷史優(yōu)質(zhì)文章推薦: 分布式系統(tǒng)的經(jīng)典基礎(chǔ)理論 可能是最漂亮的Spring事務(wù)管理詳解 面試中關(guān)于Java虛擬機(jī)(jvm)的問(wèn)題看這篇就夠了 無(wú)論是在現(xiàn)實(shí)世界中還是在軟件...

    sanyang 評(píng)論0 收藏0
  • (CZ深入淺出Java基礎(chǔ))設(shè)計(jì)模式筆記

    摘要:在設(shè)計(jì)模式中,所有的設(shè)計(jì)模式都遵循這一原則。其實(shí)就是說(shuō)在應(yīng)用程序中,所有的類如果使用或依賴于其他的類,則應(yīng)該依賴這些其他類的抽象類,而不是這些其他類的具體類。使用設(shè)計(jì)模式是為了可重用代碼讓代碼更容易被他人理解保證代碼可靠性。 這是劉意老師的JAVA基礎(chǔ)教程的筆記講的賊好,附上傳送門 傳智風(fēng)清揚(yáng)-超全面的Java基礎(chǔ) 一、面向?qū)ο笏枷朐O(shè)計(jì)原則 1.單一職責(zé)原則 其實(shí)就是開(kāi)發(fā)人員經(jīng)常說(shuō)的高...

    李昌杰 評(píng)論0 收藏0
  • Spring框架之我見(jiàn)(一)——工廠模式

    摘要:相對(duì)于工廠模式,抽象工廠模式生產(chǎn)的對(duì)象更加具體,也更加豐富,但相對(duì)編碼也更加復(fù)雜。具體的抽象工廠模式的實(shí)現(xiàn)大家可以參考菜鳥(niǎo)教程。知道了工廠模式和抽象工廠模式的區(qū)別,請(qǐng)大家使用的時(shí)候應(yīng)該根據(jù)具體的情況進(jìn)行選擇。 大家好,今天給大家分享一些Spring的學(xué)習(xí)心得,在講Spring之前,先和大家分享Spring中核心的設(shè)計(jì)模式。 工廠模式 在聊概念之前我先問(wèn)問(wèn)大家:什么是工廠? 這個(gè)很簡(jiǎn)單,...

    venmos 評(píng)論0 收藏0
  • 深入理解依賴注入

    摘要:上面這部分代碼不變,還是通過(guò)在構(gòu)造器中傳入依賴的方式初始化依賴調(diào)用這里,調(diào)用方無(wú)需了解內(nèi)部對(duì)的依賴。而配置一般用于上自動(dòng)掃描并注入的代碼如下這里只給出直接在依賴對(duì)象上添加注解的形式,還可以通過(guò)構(gòu)造器和注入依賴,這里就不多說(shuō)了。 前言 相信所有面試java開(kāi)發(fā)的童鞋一定都被問(wèn)到過(guò)是否使用過(guò)Spring,是否了解其IOC容器,為什么不直接使用工廠模式,以及究竟IOC和DI區(qū)別在于哪里這種問(wèn)...

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

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

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<