设计模式之工厂模式(factory pattern)

工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。本文从一个具体的例子逐步深入分析,来体会三种工厂模式的应用场景和利弊。

1. 简单工厂模式

该模式对对象创建管理方式最为简单,因为其仅仅简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象,其UML类图如下:

下面我们使用手机生产来讲解该模式:

Phone类:手机标准规范类(AbstractProduct)

public interface Phone {
    void make();
}

 MiPhone类:制造小米手机(Product1)

public class MiPhone implements Phone {
    public MiPhone() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make xiaomi phone!");
    }
}

IPhone类:制造苹果手机(Product2)

public class IPhone implements Phone {
    public IPhone() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make iphone!");
    }
}

PhoneFactory类:手机代工厂(Factory)

public class PhoneFactory {
    public Phone makePhone(String phoneType) {
        if(phoneType.equalsIgnoreCase("MiPhone")){
            return new MiPhone();
        }
        else if(phoneType.equalsIgnoreCase("iPhone")) {
            return new IPhone();
        }
        return null;
    }
}

 演示:

public class Demo {
    public static void main(String[] arg) {
        PhoneFactory factory = new PhoneFactory();
        Phone miPhone = factory.makePhone("MiPhone");            // make xiaomi phone!
        IPhone iPhone = (IPhone)factory.makePhone("iPhone");    // make iphone!
    }
}

2. 工厂方法模式(Factory Method)

和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,其UML类图如下:

也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。

接下来继续使用生产手机的例子来讲解该模式。

其中和产品相关的Phone类、MiPhone类和IPhone类的定义不变。

AbstractFactory类:生产不同产品的工厂的抽象类

public interface AbstractFactory {
    Phone makePhone();
}

XiaoMiFactory类:生产小米手机的工厂(ConcreteFactory1)

public class XiaoMiFactory implements AbstractFactory{
    @Override
    public Phone makePhone() {
        return new MiPhone();
    }
}

AppleFactory类:生产苹果手机的工厂(ConcreteFactory2)

public class AppleFactory implements AbstractFactory {
    @Override
    public Phone makePhone() {
        return new IPhone();
    }
}

演示:

public class Demo {
    public static void main(String[] arg) {
        AbstractFactory miFactory = new XiaoMiFactory();
        AbstractFactory appleFactory = new AppleFactory();
        miFactory.makePhone();            // make xiaomi phone!
        appleFactory.makePhone();        // make iphone!
    }
}

3. 抽象工厂模式(Abstract Factory)

上面两种模式不管工厂怎么拆分抽象,都只是针对一类产品Phone(AbstractProduct),如果要生成另一种产品PC,应该怎么表示呢?

最简单的方式是把2中介绍的工厂方法模式完全复制一份,不过这次生产的是PC。但同时也就意味着我们要完全复制和修改Phone生产管理的所有代码,显然这是一个笨办法,并不利于扩展和维护。

抽象工厂模式通过在AbstarctFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生产该产品。否则继承的这个接口可以什么也不干。

其UML类图如下:

从上面类图结构中可以清楚的看到如何在工厂方法模式中通过增加新产品接口来实现产品的增加的。

接下来我们继续通过小米和苹果产品生产的例子来解释该模式。

为了弄清楚上面的结构,我们使用具体的产品和工厂来表示上面的UML类图,能更加清晰的看出模式是如何演变的:

PC类:定义PC产品的接口(AbstractPC)

public interface PC {
    void make();
}

MiPC类:定义小米电脑产品(MIPC)

public class MiPC implements PC {
    public MiPC() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make xiaomi PC!");
    }
}

MAC类:定义苹果电脑产品(MAC)

public class MAC implements PC {
    public MAC() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make MAC!");
    }
}

下面需要修改工厂相关的类的定义:

AbstractFactory类:增加PC产品制造接口

public interface AbstractFactory {
    Phone makePhone();
    PC makePC();
}

XiaoMiFactory类:增加小米PC的制造(ConcreteFactory1)

public class XiaoMiFactory implements AbstractFactory{
    @Override
    public Phone makePhone() {
        return new MiPhone();
    }
    @Override
    public PC makePC() {
        return new MiPC();
    }
}

AppleFactory类:增加苹果PC的制造(ConcreteFactory2)

public class AppleFactory implements AbstractFactory {
    @Override
    public Phone makePhone() {
        return new IPhone();
    }
    @Override
    public PC makePC() {
        return new MAC();
    }
}

演示:

public class Demo {
    public static void main(String[] arg) {
        AbstractFactory miFactory = new XiaoMiFactory();
        AbstractFactory appleFactory = new AppleFactory();
        miFactory.makePhone();            // make xiaomi phone!
        miFactory.makePC();                // make xiaomi PC!
        appleFactory.makePhone();        // make iphone!
        appleFactory.makePC();            // make MAC!
    }
}

总结:

上面介绍的三种工厂模式有各自的应用场景,实际应用时能解决问题满足需求即可,可灵活变通,无所谓高级与低级。

此外无论哪种模式,由于可能封装了大量对象和工厂创建,新加产品需要修改已定义好的工厂相关的类,因此对于产品和工厂的扩展不太友好,利弊需要权衡一下。

(0)

相关推荐

  • 一篇带你读懂工厂模式

    工厂模式 简单工厂模式 意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行 主要解决:主要解决接口选择的问题. 何时使用:我们明确地计划不同条件下创建 ...

  • 【设计模式】(四)抽象工厂模式(Abstract Factory Pattern)

    【设计模式】(四)抽象工厂模式(Abstract Factory Pattern)

  • 【C++设计模式二】C++工厂模式

    (1)定义 简单工厂模式中,每新增一个具体产品,就需要修改工厂类内部的判断逻辑.为了不修改工厂类,遵循开闭原则,工厂方法模式中不再使用工厂类统一创建所有的具体产品,而是针对不同的产品设计了不同的工厂, ...

  • java设计模式2————工厂模式

    java设计模式2————工厂模式

  • 漫谈golang设计模式 简易工厂模式

    目前学习golang的主要需求是为了看懂TiDB的源码,下面我们复习一下简易工厂模式的思想 工厂类型分为三种,创建型模式,结构型模式,行为型模式. 简单工厂 使用场景:考虑一个简单的API设计,一个模 ...

  • 设计模式之工厂模式(下篇)

    今天我们来讲一讲抽象工厂: 重要涉及原则:要依赖抽象,不要依赖具体. 首先我们需要了解一个设计原则--依赖倒置原则:减少对具体的依赖,所谓的倒置是倒置的                         ...

  • 设计模式:工厂模式,解除耦合的利器

    工厂模式是使用频率很高的一种设计模式,在面试中也经常问到,今天我们就来学习它. 为什么要用工厂模式? 解答这个问题前,我们先来了解什么是工厂模式. 工厂模式其实也称创建模式,是用于创建对象的一种方式. ...

  • 设计模式——抽象工厂模式

    抽象工厂方法_将关联组件组装成产品 ** * 印刷抽象工厂类 * @author maikec * 2019/5/20 */ public abstract class AbstractPrintin ...

  • 设计模式之工厂模式(四)

    上篇我们从理论上了解了什么是工厂方法模式,也知道了创建者类和产品类的主要作用是什么.更重要的是,我们还学到了一个设计原则依赖倒置原则,这个原则能推导出我们为什么会使用工厂模式. 当然啦,上次还留下几个 ...

  • 设计模式之工厂模式(三)

    上一次我们已经通过代码,简单的认识了工厂方法模式,具体的思路请移步到设计模式之工厂模式(二),进行查看.这次,让我们通过设计模式的思想,来好好认识下工厂方法模式. 创建者和产品 所有工厂模式都用来封装 ...

  • 设计模式-工厂模式

    工厂模式 当我们创建一个对象比较复杂时且客户端不关心于实例对象的创建过程时我们可以用工厂模式 类型: 简单工厂模式 工厂方法模式 抽象工厂模式 简单工厂模式 百度百科 简单工厂模式是属于创建型模式,又 ...