java設(shè)計(jì)模式1:工廠模式(分類\優(yōu)缺點(diǎn)\使用選擇)

引言: 在我們開發(fā)過(guò)程中,前期可能為了趕進(jìn)度,比較注重業(yè)務(wù)功能上的走通,沒太留意代碼的易讀性,可維護(hù)性。因此呢,前人也是總結(jié)了23種設(shè)計(jì)模式,來(lái)幫助我們更優(yōu)雅地進(jìn)行代碼重構(gòu)、或者工具類編寫、中間件設(shè)計(jì)等。筆者最近也是通過(guò)回顧和進(jìn)一步深入學(xué)習(xí),來(lái)總結(jié)常用的一些設(shè)計(jì)模式。有不足之處,歡迎留言共同討論哦~。

1、工廠模式分類

《設(shè)計(jì)模式篇》第一篇,我們來(lái)聊聊工廠模式。
所謂工廠,就是用來(lái)生產(chǎn)東西的,那么對(duì)于java中的工廠模式,就是用來(lái)生產(chǎn)對(duì)象的。按對(duì)象和工廠的關(guān)系,我們可以分為三類模式:

  • 簡(jiǎn)單工廠,所有對(duì)象都來(lái)源同一個(gè)工廠
  • 工廠模式,每個(gè)對(duì)象都有自己的工廠
  • 抽象工廠,每個(gè)對(duì)象需要在使用的時(shí)候才確認(rèn)具體長(zhǎng)啥樣,可以產(chǎn)生一組相似對(duì)象。
    下面我們通過(guò)代碼來(lái)詳細(xì)看看他們的區(qū)別和利弊。

2、優(yōu)缺點(diǎn)分析

首先看下簡(jiǎn)單工廠 :

//簡(jiǎn)單工廠
public class SimpleFactory {


    public Object  create(String name){

        if(name==null || name.replace(" ","").length()==0) return null;

        if("nike".equals(name)){
            return new Nike();
        }else if("addidas".equals(name)){
            return new Addidas();
        }
        return null;
    }

    /**  測(cè)試
     *   依次打印 nike inited 、Addidas inited
     * @param args
     */
    public static void main(String[] args) {

        SimpleFactory simpleFactory = new SimpleFactory();
        Nike nike = (Nike)simpleFactory.create("nike");
        nike.doSth();
        Addidas addidas = (Addidas)simpleFactory.create("addidas");
        addidas.doSth();
    }
    
}
//待創(chuàng)建
class Nike{

    void doSth(){
        System.out.println("nike inited");
    }
}
//待創(chuàng)建
class Addidas{

    void doSth(){
        System.out.println("Addidas inited");
    }
}

簡(jiǎn)單工廠優(yōu)缺點(diǎn)分析 :
很明顯,簡(jiǎn)單工廠創(chuàng)建對(duì)象的方式就是根據(jù)一個(gè)字符串名字來(lái)創(chuàng)建的,我們需要什么對(duì)象就傳進(jìn)對(duì)應(yīng)的字符串。這種方式也挺靈活適用很多場(chǎng)景,只需知道對(duì)象名稱就能得到對(duì)應(yīng)的對(duì)象; 但是這種工廠類寫法有個(gè)前提,就是我們已經(jīng)確定下來(lái)需要哪些對(duì)象, 那么一旦有新的變更,那就要修改工廠類,這樣就不符合開閉原則(已封裝好的東西盡量不修改)。那么當(dāng)我們不知道到底需要多少對(duì)象,這時(shí)候咋辦呢,工廠模式對(duì)此做了進(jìn)一步深化:

來(lái)看下代碼 :

//鞋類接口,定義鞋子
public interface IShoes {
    //品牌
    void logo();
    //種類
    void kind();
}

//Addidas 鞋子
class Addidas implements IShoes{

    @Override
    public void logo() {
        System.out.println("logo - addidas");
    }

    @Override
    public void kind() {
        System.out.println("addidas - sport");
    }
}

//Nike 鞋子
class  Nike implements IShoes{

    @Override
    public void logo() {
        System.out.println("logo - nike");
    }

    @Override
    public void kind() {
        System.out.println("nike - sport");
    }
}

abstract  class AbstractShoesFactory{

    abstract  IShoes create();
}

//Nike鞋子的獨(dú)立工廠
class  NikeFactory  extends AbstractShoesFactory{

    @Override
    IShoes create() {
        return new Nike();
    }
}

// Addida 鞋子的獨(dú)立工廠
class AddidasFactory extends AbstractShoesFactory{

    @Override
    IShoes create() {
        return new Addidas();
    }
}

//測(cè)試效果
class Test{

    /** 依次輸出:
     * logo - nike
     * nike - sport
     * logo - addidas
     * addidas - sport
     */
    public static void main(String[] args) {

        NikeFactory nikeFactory = new NikeFactory();
        IShoes iShoes = nikeFactory.create();
        iShoes.logo();
        iShoes.kind();

        AddidasFactory addidasFactory = new AddidasFactory();
        IShoes iShoes1 = addidasFactory.create();
        iShoes1.logo();
        iShoes1.kind();
    }

}

可以看出,工廠模式中,每個(gè)對(duì)象都有自己的工廠,當(dāng)我們需要新的對(duì)象時(shí),只需要新建一個(gè)對(duì)象的工廠就好。不需要修改主工廠類的代碼,這樣就更符合開閉原則。而且在設(shè)計(jì)比較復(fù)雜的邏輯時(shí),每個(gè)對(duì)象有自己工廠類的劃分,不用像簡(jiǎn)單工廠全部擠在一起,這樣更方便維護(hù)。
但是也有個(gè)缺點(diǎn),就是只能生產(chǎn)單一確定的對(duì)象,當(dāng)我們想生產(chǎn)一組近似的對(duì)象,有時(shí)候只相差一個(gè)方法,如果這時(shí)候再特地創(chuàng)建工廠類,未免不太靈活,為此,我們有了抽象工廠模式:

//抽象工廠模式,可以生產(chǎn)一組對(duì)象
//制作鞋子Logo
interface ILogo {
    void makeLogo();
}
//制作鞋子品類
interface IKind{
    void makeKind();
}
//鞋子制作工廠
interface IShoesFactory{

    ILogo madeLogo();
    IKind madeKind();
}

//Addidas鞋Logo制作
class  AddidasLogo implements  ILogo{

    @Override
    public void makeLogo() {
        System.out.println("制作阿迪達(dá)斯Logo");
    }
}

//Addidas鞋類制作
class  AddidasKind implements IKind{

    @Override
    public void makeKind() {
        System.out.println("制作阿迪達(dá)斯運(yùn)動(dòng)鞋");
    }
}

// Addidas鞋子制作工廠
class AddidasFactory implements IShoesFactory{

    @Override
    public ILogo madeLogo() {
        return new AddidasLogo();
    }

    @Override
    public IKind madeKind() {
        return new AddidasKind();
    }
}

//測(cè)試效果
class Test{
    public static void main(String[] args) {
        AddidasFactory addidasFactory = new AddidasFactory();
        addidasFactory.madeLogo().makeLogo();
        addidasFactory.madeKind().makeKind();
    }
}

好了,以上就是工廠模式的三種簡(jiǎn)單介紹,最后再簡(jiǎn)單總結(jié)下使用上的選擇:

3、使用選擇

  • 首先三種工廠模式使用的共有前提,就是需要大量創(chuàng)建使用某些對(duì)象的時(shí)候,為了提高代碼的復(fù)用率和方便統(tǒng)一維護(hù),我們可以使用該模式。
  • 當(dāng)我們已經(jīng)確定下來(lái)需要哪些對(duì)象,優(yōu)先使用簡(jiǎn)單工廠模式。
  • 當(dāng)我們不確定對(duì)象到底需要多少,則使用工廠模式。
  • 當(dāng)我們使用的對(duì)象,要在使用的時(shí)候才能確定到底長(zhǎng)啥樣,就使用抽象工廠。

以上就是個(gè)人在學(xué)習(xí)過(guò)程中對(duì) 工廠模式的總結(jié),由于筆者能力有限,難免有疏漏的地方,有不足或者不太清楚的地方,歡迎留言討論,共同進(jìn)步-==

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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