Java设计模式——Factory工厂模式

针对Java设计模式,推荐一书《大话设计模式》:
链接: https://pan.baidu.com/s/16YZ8nMx6M2C94_dmMWjh0w 提取码: aw5y

Factory工厂模式分为:

1)简单工厂模式(Simple Factory) --- 普通工厂模式
2)工厂方法模式(Factory Method) --- 多工厂模式
3)抽象工厂模式(Abstract Factory) --- 抽象工厂模式

什么时候需要用工厂模式呢?

工厂,从字面意思理解,就是造东西的地方。所以,需要很多类型或者经常升级换代,就可以使用工厂模式。比如,宝马工厂,它有很多产品,而且每一款产品还时不时地升个级,换个代,所以就有工厂这个东西。
所以,使用工厂模式,你需要确定一点:
工厂模式针对的是多态。也就是说,你的类型如果可能有很多派生,使用工厂模式比较方便。
如果你的需求是经常会添加的,比如会添加某个方法,那么使用工厂模式反而很麻烦,因为你要修改一连串的项目文件

所以,工厂模式的适用场景大致有这些:
1)对象的创建过程(实例化)很复杂,需要初始化很多参数,比如查询数据库等。
2)类本身有好多子类,这些类的创建过程在业务中容易发生改变,或者对类的调用容易发生改变。

工厂模式的优点

1)解耦:把对象的创建和使用的过程分开
ClassA想调用ClassB(其实只是想调用B的方法)不再需要New一个B,B的实例化,就交给工厂类。

2)统一管理对象的创建过程,降低代码重复
如果很多地方都需要创建对象B(创建过程复杂),那么很多地方都需要New B(),此时代码重复就比较多。
如果把创建对象B的代码放到工厂里统一管理,既减少了重复代码,也方便以后对B的创建过程的修改维护。

引子

中国有16亿人,如果每人想买一辆宝马,只需要告诉工厂,你想买什么类型的宝马,是宝马320还是宝马523……工厂直接生产出来给你就好了,这就是通俗理解工厂模式!通俗理解其好处就是:方便更改应用程序和扩展。

工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。

也有的人将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。所以实际分为两类:工厂方法模式与抽象工厂模式,两者区别如下:
(1)工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。
(2)工厂方法模式只有一个抽象工厂类,而抽象工厂模式有多个抽象工厂类。
(3)工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个具体产品类的实例。

public class BMW320 {
    public BMW320(){
        System.out.println("制造-->BMW320");
    }
}
 
public class BMW523 {
    public BMW523(){
        System.out.println("制造-->BMW523");
    }
}
 
public class Customer {
    public static void main(String[] args) {
        BMW320 bmw320 = new BMW320();
        BMW523 bmw523 = new BMW523();
    }
}

这个例子,客户必须要知道怎么去创建一款车才可以,这样的话,客户和车就紧密耦合在一起了。为了降低耦合,就出现了工厂类,把创建宝马的操作细节都放到了工厂里面去,客户直接使用工厂的创建工厂方法,传入想要的宝马车型号就行了,而不必去知道创建的细节,这就是简单工厂模式了!
即我们建立一个工厂类方法来制造新的对象,如图:


简单工厂模式.jpg
//  产品类
abstract class BMW {
    public BMW(){
        
    }
}
 
public class BMW320 extends BMW {
    public BMW320() {
        System.out.println("制造-->BMW320");
    }
}
public class BMW523 extends BMW{
    public BMW523(){
        System.out.println("制造-->BMW523");
    }
}
// 工厂类
public class Factory {
    public BMW createBMW(int type) {
        switch (type) { 
        case 320:
            return new BMW320();
        case 523:
            return new BMW523();
        default:
            break;
        }
        return null;
    }
}
// 客户类
public class Customer {
    public static void main(String[] args) {
        Factory factory = new Factory();
        BMW bmw320 = factory.createBMW(320);
        BMW bmw523 = factory.createBMW(523);
    }
}

简单工厂模式又称静态工厂方法模式,它存在的目的很简单:定义一个用于创建对象的接口。 先来看看它的组成:

  1. 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
  2. 抽象产品角色:它一般是具体产品继承的父类或者实现的接口
  3. 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
    好了,现在假若客户想要增加车型,比如奔驰、保时捷……那么,就需要在工厂类中增加相应的创建业务逻辑,如果需要增加大量车型,那就得吐血了,所以,就出现了工厂方法模式 。

------- 工厂方法模式 ---------
工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承,这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
工厂方法模式组成:
1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
看如下代码:

// 产品类
abstract class BMW {
    public BMW(){
        
    }
}
public class BMW320 extends BMW {
    public BMW320() {
        System.out.println("制造-->BMW320");
    }
}
public class BMW523 extends BMW{
    public BMW523(){
        System.out.println("制造-->BMW523");
    }
}
// 工厂类
interface FactoryBMW {
    BMW createBMW();
}
 
public class FactoryBMW320 implements FactoryBMW{
    @Override
    public BMW320 createBMW() {
        return new BMW320();
    }
}

public class FactoryBMW523 implements FactoryBMW {
    @Override
    public BMW523 createBMW() {
        return new BMW523();
    }
}
// 客户类
public class Customer {
    public static void main(String[] args) {
        FactoryBMW320 factoryBMW320 = new FactoryBMW320();
        BMW320 bmw320 = factoryBMW320.createBMW();
 
        FactoryBMW523 factoryBMW523 = new FactoryBMW523();
        BMW523 bmw523 = factoryBMW523.createBMW();
    }
}

工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口,但这样会使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,所以就出现抽象工厂模式了。

---------- 抽象工厂模式 ---------
随着客户的要求越来越高,宝马车需要不同配置的空调和发动机等配件。于是这个工厂开始生产空调和发动机,用来组装汽车。这时候工厂有两个系列的产品:空调和发动机。宝马320系列配置A型号空调和A型号发动机,宝马230系列配置B型号空调和B型号发动机。
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象,代码:

// 产品类
//发动机以及型号  
public interface Engine {  
 
}  
public class EngineA extends Engine{  
    public EngineA(){  
        System.out.println("制造-->EngineA");  
    }  
}  
public class EngineBextends Engine{  
    public EngineB(){  
        System.out.println("制造-->EngineB");  
    }  
}  
//空调以及型号  
public interface Aircondition {  
 
}  
public class AirconditionA extends Aircondition{  
    public AirconditionA(){  
        System.out.println("制造-->AirconditionA");  
    }  
}  
public class AirconditionB extends Aircondition{  
    public AirconditionB(){  
        System.out.println("制造-->AirconditionB");  
    }  
}
// 工厂类
//创建工厂的接口  
public interface AbstractFactory {  
    //制造发动机
    public Engine createEngine();
    //制造空调 
    public Aircondition createAircondition(); 
}  
//为宝马320系列生产配件  
public class FactoryBMW320 implements AbstractFactory{   
    @Override  
    public Engine createEngine() {    
        return new EngineA();  
    }  
    @Override  
    public Aircondition createAircondition() {  
        return new AirconditionA();  
    }  
}  
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {  
     @Override  
    public Engine createEngine() {    
        return new EngineB();  
    }  
    @Override  
    public Aircondition createAircondition() {  
        return new AirconditionB();  
    }  
} 
// 客户类
public class Customer {  
    public static void main(String[] args){  
        //生产宝马320系列配件
        FactoryBMW320 factoryBMW320 = new FactoryBMW320();  
        factoryBMW320.createEngine();
        factoryBMW320.createAircondition();
          
        //生产宝马523系列配件  
        FactoryBMW523 factoryBMW523 = new FactoryBMW523();  
        factoryBMW320.createEngine();
        factoryBMW320.createAircondition();
    }  
}

抽象工厂模式和工厂方法模式的区别,仔细看代码就能体会。

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

推荐阅读更多精彩内容

  • 参考资料:菜鸟教程之设计模式 设计模式概述 设计模式(Design pattern)代表了最佳的实践,通常被有经验...
    Steven1997阅读 1,127评论 1 12
  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 3,820评论 1 15
  • 一、工厂模式介绍 工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每...
    QuantRuu阅读 750评论 0 51
  • 果然没基础要多练习,配色是个硬伤,~(>_<)~ 重新买的纸昨天刚到,交的晚了。请老师帮忙指导下,谢谢
    立夏凝音阅读 229评论 2 0
  • 这几天假期,全用在陪病人上了,觉得这几天真的过得很快,今天终于冒着小雨,腾出了时间收拾一下花盆,又画了这几个小...
    哈皮翠鸟阅读 1,270评论 0 2