簡(jiǎn)單工廠模式,工廠模式,抽象工廠模式

突然有一天,在夢(mèng)里擁有了阿拉丁神燈。
燈神說(shuō): "我可以給你創(chuàng)造一個(gè)女朋友哦"
"但是只能滿足你一個(gè)地理?xiàng)l件,目前只有三個(gè)選項(xiàng): 四川, 河北, 山東. 你挑一個(gè)? " 燈神又說(shuō)。
"那我選: 四川...或者..."
沒(méi)等我說(shuō)完,嘭的一下,出來(lái)個(gè)一個(gè)火辣的川妹子...

簡(jiǎn)單工廠模式

首先創(chuàng)建妹子的類型,四川, 河北, 山東。用枚舉來(lái)表示:

public enum GirlFriendType {
    SI_CHUAN,
    HE_BEI,
    SHAN_DONG
}

然后再看看要和妹子干什么,比如購(gòu)物和吃東西,購(gòu)物是一定的了,吃東西則由每個(gè)地方的口味決定,所以創(chuàng)建一個(gè)抽象類:

public abstract class BaseGirlFriend {
    public abstract void eatFood();
    public void shopping() {
        System.out.println("天天都要購(gòu)物");
    }
}

然后創(chuàng)建三個(gè)地區(qū)的妹子實(shí)現(xiàn)類:

//四川妹子
public class SiChuangGirlFriend extends BaseGirlFriend {
    @Override
    public void eatFood() {
        Log.i("BaseGirlFriend", "吃四川辣椒。");
    }
}
//河北妹子
public class HeBeiGirlFriend extends BaseGirlFriend {
    @Override
    public void eatFood() {
        Log.i("BaseGirlFriend", "吃河北食物。");
    }
}
//山東妹子
public class ShanDongGirlFriend extends BaseGirlFriend {
    @Override
    public void eatFood() {
        Log.i("BaseGirlFriend", "吃山東包子。");
    }
}

最后創(chuàng)建一個(gè)工廠來(lái)創(chuàng)建妹子,默認(rèn)是河北的吧:

public class GirlFriendFactory {
    public static BaseGirlFriend createGirlFriend(GirlFriendType type) {
        switch (type) {
            case SI_CHUAN:
                return new SiChuangGirlFriend();
            case SHAN_DONG:
                return new ShanDongGirlFriend();
            case HE_BEI:
                return new HeBeiGirlFriend();
            default:
                return new HeBeiGirlFriend();
        }
    }
}

然后,在用的時(shí)候是這樣的:

//選擇了山東妹子一起吃飯購(gòu)物
BaseGirlFriend shandong = GirlFriendFactory.createGirlFriend(GirlFriendType.SHAN_DONG);
shandong.eatFood();
shandong.shopping();
//選擇了四川妹子一起吃飯購(gòu)物
BaseGirlFriend sichuan = GirlFriendFactory.createGirlFriend(GirlFriendType.SI_CHUAN);
sichuan.eatFood();
sichuan.shopping();
//選擇了河北妹子一起吃飯購(gòu)物
BaseGirlFriend hebei = GirlFriendFactory.createGirlFriend(GirlFriendType.HE_BEI);
hebei.eatFood();
hebei.shopping();

然后可以看出,這種簡(jiǎn)單工廠模式是有缺陷的,比如我現(xiàn)在不選這三個(gè)地區(qū)的了,我要選擇云南的妹子,那么我就需要修改枚舉類代碼,修改工廠類代碼,非常麻煩。

那么,是否可以通過(guò)一個(gè)接口,讓我喜歡選哪個(gè)地方就選哪個(gè)地方?

工廠模式

首先創(chuàng)建一個(gè)接口:

public interface IGirlFriendFactory {
    BaseGirlFriend createGirlFriend();
}

然后為每個(gè)地方的妹子都建一個(gè)工廠,并實(shí)現(xiàn)這個(gè)接口(河北為例,其他地方一樣):

public class HeBeiGirlFriendFactory implements IGirlFriendFactory {

    @Override
    public BaseGirlFriend createGirlFriend() {
        return new HeBeiGirlFriend();
    }
}

然后其他類跟之前一樣,然后在用的時(shí)候是這樣的:

IGirlFriendFactory hebeiFactory = new HeBeiGirlFriendFactory();
BaseGirlFriend hebei = hebeiFactory.createGirlFriend();
hebei.shopping();
hebei.eatFood();

可以看到,想實(shí)現(xiàn)哪個(gè)地方的妹子,只需要繼承 IGirlFriendFactory 接口就可以了,代碼也不需要修改。

有時(shí)候也可以利用反射方式更加簡(jiǎn)潔地來(lái)生產(chǎn)具體對(duì)象,需要在工廠方法的參數(shù)列表中傳入一個(gè)Class類來(lái)決定哪一個(gè)產(chǎn)品類:
修改 IGirlFriendFactory 工廠接口為:

public interface IGirlFriendFactory {
   <T extends BaseGirlFriend> T createGirlFriend(Class<T> clz);
   IGirlFriendFather createGirlFriendFather();
}

然后具體的工廠實(shí)現(xiàn)類:

public class GirlFriendFactory implements IGirlFriendFactory {

    @Override
    public <T extends BaseGirlFriend> T createGirlFriend(Class<T> clz) {
        BaseGirlFriend baseGirlFriend = null;
        try {
            baseGirlFriend = (BaseGirlFriend) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) baseGirlFriend;
    }

    @Override
    public IGirlFriendFather createGirlFriendFather() {
        return new HeBeiGirlFriendFather();
    }
}

最后在使用的時(shí)候這樣,看著是不是簡(jiǎn)潔很多:

IGirlFriendFactory factory = new GirlFriendFactory();
BaseGirlFriend hebei = factory.createGirlFriend(HeBeiGirlFriend.class);
hebei.shopping();
hebei.eatFood();

好多年以后,發(fā)現(xiàn)妹子的父母還沒(méi)見(jiàn)啊,不知道父母同不同意。然后我們?nèi)フ疑駸舸蟾鐜兔Α?/p>

抽象工廠模式

創(chuàng)建妹子父母接口,以父親為例:

public interface IGirlFriendFather {
    // 對(duì)于閨女和我的事情的建議
    void suggestionToGirl();
}

然后實(shí)現(xiàn)這個(gè)接口(同意或不同意或其他),以河北妹子為例:

public class HeBeiGirlFriendFather implements IGirlFriendFather {
    @Override
    public void suggestionToGirl() {
        Log.i("BaseGirlFriend", "我同意了。");
    }
}

然后再工廠接口里面增加一個(gè)創(chuàng)建妹子父親的方法:

public interface IGirlFriendFactory {
    BaseGirlFriend createGirlFriend();
    IGirlFriendFather createGirlFriendFather();
}

所以河北妹子實(shí)現(xiàn)類:

public class HeBeiGirlFriendFactory implements IGirlFriendFactory {

    @Override
    public BaseGirlFriend createGirlFriend() {
        return new HeBeiGirlFriend();
    }

    @Override
    public IGirlFriendFather createGirlFriendFather() {
        return new HeBeiGirlFriendFather();
    }
}

最后在用的時(shí)候,通過(guò)工廠創(chuàng)建妹子的父親,并調(diào)用方法發(fā)表意見(jiàn):

IGirlFriendFactory hebeiFactory = new HeBeiGirlFriendFactory();
BaseGirlFriend hebei = hebeiFactory.createGirlFriend();
hebei.shopping();
hebei.eatFood();

//創(chuàng)建妹子父親
IGirlFriendFather hebeiFather = hebeiFactory.createGirlFriendFather();
hebeiFather.suggestionToGirl();

參考自
ocoaChinabbs
《Android源碼設(shè)計(jì)模式解析與實(shí)踐》

最后編輯于
?著作權(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)容

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