设计模式——工厂模式

一、什么是工厂模式?

 

工厂模式就是创建一个对象的工厂接口,创建对象不再是通过new这个对象来直接实现,而是通过工厂来对对象进行创建。应用工厂模式可以降低系统间的耦合度。


工厂模式中一般有以下角色:


1. 抽象产品类:是具体产品对象的基类


2. 具体产品类:实现了抽象产品类接口,每一个具体产品类都会对应一个工厂


3. 抽象工厂:工厂模式的基类,定义了工厂类必须实现的接口


4. 具体工厂:实现了抽象工厂类的接口,是与客户端直接交互的类,负责具体的产品对象的创建


我们平时都是通过new来创建一个对象实例的,假设我们在多个方法中都对类A进行了实例化,而现在我们需要对A做一点改动,比如我们要修改A的构造方法的入参,那么接下来会发生什么?那就是我们需要修改所有实例化A类的代码,这个改动量无疑是巨大的,而且我们也不保证在改动的过程中不会出错。这样的一种对象创建模式无疑违反了设计模式中的“开放关闭原则”(即对扩展开放,对修改关闭)。这个时候应用工厂模式就是很合适的,对象实例是通过工厂来创建的,如果我们要修改或者扩展类A,我们不再需要修改所有实例化A的地方,而只是需要修改对应的工厂类即可。


工厂模式分有两种,简单工厂模式和工厂模式。简单工厂模式即静态工厂模式,是一个用来实例化目标类的静态类。工厂模式是一个具体工厂对应一个具体目标对象。


二、工厂模式框图


我们通过买包子这个例子来讲述下工厂模式在其中的应用,并比较下静态工厂和工厂模式。


先来看下静态工厂模式:


 

图1. 静态工厂模式框图


现在看下工厂模式:


 

图2. 工厂模式框图


三、工厂模式的具体代码

 

3.1 Bun接口,包子抽象类,内部有一个stuffing方法,显示是什么馅

package designpatterns.factory;

/**
 * Created by Olive on 2017/12/18.
 * 包子的接口
 */
public interface Bun {
    // 显示是什么馅
    void stuffing();
}

3.2 BunFactory接口,抽象包子工厂类,有一个getBun方法,返回一个包子实例

package designpatterns.factory;

/**
 * Created by Olive on 2017/12/18.
 * 抽象包子工厂接口
 */
public interface BunFactory {
    Bun getBun();
}

3.3 BeefBun类,牛肉馅的包子,实现了Bun接口

package designpatterns.factory;

/**
 * Created by Olive on 2017/12/18.
 */
public class BeefBun implements Bun{

    public void stuffing() {
        System.out.println("Beef Bun!");
    }
}

3.4 PorkBun类,大肉馅(不清真 = =)的包子,实现了Bun接口

package designpatterns.factory;

/**
 * Created by Olive on 2017/12/18.
 * 猪肉包子类(Emmmm,一点都不清真)
 */
public class PorkBun implements Bun{

    public void stuffing() {
        System.out.println("Pork Bun!");
    }
}

3.5 BeefBunFactory类,牛肉包子工厂,只做牛肉包子,实现了BunFactory接口

package designpatterns.factory;

/**
 * Created by Olive on 2017/12/18.
 */
public class BeefBunFactory implements BunFactory{

    public Bun getBun() {
        return new BeefBun();
    }
}

3.6 PorkBunFactory类,猪肉包子工厂,只做猪肉包子,实现了BunFactory接口

package designpatterns.factory;

/**
 * Created by Olive on 2017/12/18.
 */
public class PorkBunFactory implements BunFactory{

    public Bun getBun() {
        return new PorkBun();
    }
}

3.7 BunsStaticFactory,静态包子工厂,什么包子都做

package designpatterns.factory;

/**
 * Created by Olive on 2017/12/18.
 * 静态包子工厂
 */
public class BunsStaticFactory {

    public static Bun getPorkBun(){
        return new PorkBun();
    }

    public static Bun getBeefBun(){
        return new BeefBun();
    }
}

3.8 Client,客户端

package designpatterns.factory;

/**
 * Created by Olive on 2017/12/18.
 * 客户,来买包子
 */
public class Client {

    public static void main(String[] args){

        // 静态工厂
        Bun pork = BunsStaticFactory.getPorkBun();
        pork.stuffing();

        Bun beef = BunsStaticFactory.getBeefBun();
        beef.stuffing();

        System.out.println("*******************");

        // 普通工厂
        Bun porkBun = new PorkBunFactory().getBun();
        porkBun.stuffing();

        Bun beefBun = new BeefBunFactory().getBun();
        beefBun.stuffing();

    }
}

3.8 结果

Pork Bun!
Beef Bun!
*******************
Pork Bun!
Beef Bun!

Process finished with exit code 0


四、一点小总结

 

  静态工厂模式通过在工厂中建立静态方法来获得目标对象实例,但是静态工厂模式是不完全满足“开放关闭原则”的,例子中如果要增加一个“豆沙包”类,则需要在静态工厂类中增加“获取豆沙包”的方法。而工厂模式是完全满足“开放关闭原则”的,静态工厂模式只有一个工厂类,而工厂模式有一组实现了相同接口的工厂类


  从上述的类图中可以看到,在结构上来说,静态工厂模式更加简单,工厂模式的工厂类会随着产品种类的增多而增多,这会使系统中有很多个工厂类,使结构更加复杂。而在设计模式的角度来看,工厂模式具有相当好的扩展性。这两种模式各有千秋,需要根据实际情况来选用。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值