设计模式——工厂模式

来源:互联网 发布:面向过程的编程思想 编辑:程序博客网 时间:2024/06/07 01:17

一、什么是工厂模式?

 

工厂模式就是创建一个对象的工厂接口,创建对象不再是通过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


四、一点小总结

 

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


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