设计模式—创建型模式—工厂方法模式

工厂方法模式,工厂就是用来生产的,在Java中我们用工厂来生产对象,
工厂方法模式分为简单工厂模式(Simple Factory)工厂方法模式(Factory Method)抽象工厂模式(Abstract Factory),在23种设计模式中不包含简单工厂模式,它可以看做工厂模式的一种特例。

简单工厂模式

通过一个代码看下,什么是简单工厂模式

比如我们有个手机产品的对象,如果我们要制作手机的话,就需要自己去new()手机,这样如何制作手机都需要我们自己去完成。如果我们把这件事交给工厂去做,我们只需要告诉工厂我们需要什么样的手机,我不管你是怎么做的,我只要告诉你型号,你就的给我制作出来。

我们有个手机这个产品的抽象接口,我们的产品分别是小米手机和华为手机

public interface Cellphone {
    void call();
}

public class XiaoMi implements Cellphone {
    @Override
    public void call() {
        System.out.println("小米手机");
    }
}
public class HuaWei implements Cellphone {
    @Override
    public void call() {
        System.out.println("华为手机");
    }
}

这时候的简单工厂为:

public class SimpleFactory {
    public static Cellphone createCellphone(String type) {
        Cellphone cellphone = null;
        if ("小米".equals(type)) {
            cellphone = new XiaoMi();
        }
        if ("华为".equals(type)) {
            cellphone = new HuaWei();
        }
        return cellphone;
    }
}

客户

public static void main(String[] args) {
        Cellphone xm = SimpleFactory.createCellphone("小米");
        xm.call();
}

简单工厂很好理解,工厂根据不同的参数去创建不同的产品。如果这时候我们增加了一样产品,就需要去修改工厂类,增加一种if判断,这显然是不符合开闭原则(对扩展开放;对修改封闭)。因为每增加一种产品,工厂都需要增加对应的创建逻辑。为了解决这个问题,有了工厂方法模式

工厂方法模式

为了解决上面提到的简单工厂的问题,我们可以给手机的工厂类创建对应的工厂子类,这些工厂分别实现工厂的抽象接口,这样我们通过实例化不同的工厂子类,调用其创建方法就能得到不同的手机,这是多态的表现。这时候我们的工厂抽象类如下

public interface PhoneFactory {
    Cellphone createCellphone();
}

小米工厂

public class XiaoMiPhoneFactory implements PhoneFactory {
    @Override
    public Cellphone createCellphone() {
        return new XiaoMi();
    }
}

华为工厂

public class HuaWeiPhoneFactory implements PhoneFactory {
    @Override
    public Cellphone createCellphone() {
        return new HuaWei();
    }
}

这个时候客户想要制作手机,只需要告诉不同的工厂即可

public class Custom {
    public static void main(String[] args) {
        PhoneFactory xiaoMiPhoneFactory = new XiaoMiPhoneFactory();
        PhoneFactory huaWeiPhoneFactory = new HuaWeiPhoneFactory();
        Cellphone c1 = xiaoMiPhoneFactory.createCellphone();
        c1.call();
        Cellphone c2 = huaWeiPhoneFactory.createCellphone();
        c2.call();
    }
}
//结果
小米手机
华为手机

每个手机子类都对应着一个工厂类子类,利用多态的方式创建对象的方式,就是工厂方法模式。如果后期我们的产品种类越来越多,那我们的工厂子类会越来越多,比如我们产品不单单是手机了,还有电脑,手机还分4G手机和5G手机,电脑分i5电脑和i7电脑;这样我们的产品种类这么多,我们不可能给每个产品种类都创建一个工厂子类,为了解决这个问题,我们来看下抽象工厂模式

抽象工厂模式

根据上面的问题,我们的工厂创建的产品示意图大概如下所示:

这个时候产品种类众多,对应的工厂子类众多,那么我们不能为每个产品都创建工厂子类了,而是把产品分组,为每个组创建一个工厂。

此时的手机和电脑产品接口
public interface Cellphone {
    void call();
}
public interface Computer {
    void cal();
}

小米的产品

public class XiaoMi4g implements Cellphone {
    @Override
    public void call() {
        System.out.println("小米4G手机");
    }
}
public class XiaoMi5g implements Cellphone {
    @Override
    public void call() {
        System.out.println("小米5G手机");
    }
}
public class XiaoMiI5 implements Computer {
    @Override
    public void cal() {
        System.out.println("小米i5电脑");
    }
}
public class XiaoMiI7 implements Computer {
    @Override
    public void cal() {
        System.out.println("小米i7电脑");
    }
}

华为的产品

public class HuaWei4g implements Cellphone {
    @Override
    public void call() {
        System.out.println("华为4g手机");
    }
}
public class HuaWei5g implements Cellphone {
    @Override
    public void call() {
        System.out.println("华为5g手机");
    }
}
public class HuaWeiI5 implements Computer {
    @Override
    public void cal() {
        System.out.println("华为i5电脑");
    }
}
public class HuaWeiI7 implements Computer {
    @Override
    public void cal() {
        System.out.println("华为i7电脑");
    }
}

此时的抽象工厂

public interface Factory {
    //制作4g手机
    Cellphone create4gCellphone();

    //制作5g手机
    Cellphone create5gCellphone();

    //制作i5电脑
    Computer createI5Computer();

    //制作i7电脑
    Computer createI7Computer();
}

小米工厂

public class XiaoMiFactory implements Factory {

    @Override
    public Cellphone create4gCellphone() {
        return new XiaoMi4g();
    }

    @Override
    public Cellphone create5gCellphone() {
        return new XiaoMi5g();
    }

    @Override
    public Computer createI5Computer() {
        return new XiaoMiI5();
    }

    @Override
    public Computer createI7Computer() {
        return new XiaoMiI7();
    }
}

华为工厂

public class HuaWeiFactory implements Factory {

    @Override
    public Cellphone create4gCellphone() {
        return new HuaWei4g();
    }

    @Override
    public Cellphone create5gCellphone() {
        return new HuaWei5g();
    }

    @Override
    public Computer createI5Computer() {
        return new HuaWeiI5();
    }

    @Override
    public Computer createI7Computer() {
        return new HuaWeiI7();
    }
}

客户, 通过实例化不同的工厂子类,调用不同的创建方法,可以创建出不同的产品:

public class Custom {
    public static void main(String[] args) {
        Factory xiaomi = new XiaoMiFactory();
        Cellphone gCellphone = xiaomi.create4gCellphone();
        gCellphone.call();

        Factory huawei = new HuaWeiFactory();
        Computer i5Computer = huawei.createI5Computer();
        i5Computer.cal();
    }
}

刚才上面的代码,我们把产品分为小米的产品和华为的产品,通过调用小米工厂和华为工厂的不同方法来创建不同的产品,这样的模式为抽象工厂模式.

总结:来自程序员小灰

简单工厂模式:

简单工厂模式有唯一的工厂类,工厂类的创建方法根据传入的参数做if-else条件判断,决定最终创建什么样的产品对象。

工厂方法模式:

工厂方法模式由多个工厂类实现工厂接口,利用多态来创建不同的产品对象,从而避免了冗长的if-else条件判断。

抽象工厂模式:

抽象工厂模式把产品子类进行分组,同组中的不同产品由同一个工厂子类的不同方法负责创建,从而减少了工厂子类的数量。

纸上得来终觉浅,绝知此事要躬行 😊

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352