什么是工厂模式(创建型-工厂模式(Factory Pattern))

时间:2024-07-31 08:15:33    100次浏览

  我们来学习工厂模式,有的小伙伴可能会说起航篇里的大纲中没有这个模式呀,这是从哪冒出来的。事实确实如此,工厂模式包含了简单工厂模式、工厂方法模式和抽象工厂模式。

  简单工厂模式也没有在大纲中出现,这个是较早出现的工厂模式。

  什么是工厂模式

  大白话来说就是,当我们需要一个对象时,不需要知道具体的创建过程,只需要问工厂要即可。由此可见,工厂的作用就是为我们创建对象。

  举个栗子,比如你要去买书,可能想买《Java编程思想》,也可能是《Effective Java》又或者是《深入理解Java虚拟机》,这种情况下直接去书店就能满足你的需求。这里的书店就充当工厂的作用。

  简单工厂(Simple Factory)

  简单工厂模式也叫静态工厂方法,根据传入的参数不同返回相应的对象。实现该方法所在的类就是简单工厂类。如下图所示:

  这里以支付为例,日常生活中大家在付款时,用的比较多的就是支付宝和微信了。根据这个场景我们来实现简单工厂的代码。

  第一步:创建支付接口

/**
 * 第一步:创建抽象产品接口,定义抽象方法,让具体的产品类去实现具体业务
 */
public interface IPay {

    /**
     * 定义统一支付方法
     */
    void unifiedorder();
}12345678910复制代码类型:[java]

  第二步:创建具体的业务实现

/**
 * 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
 */
public class AliPay implements IPay {

    @Override
    public void unifiedorder() {
        System.out.println("调用阿里支付");
    }
}

/**
 * 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
 */
public class WechatPay implements IPay{

    @Override
    public void unifiedorder() {
        System.out.println("调用微信支付");
    }
}123456789101112131415161718192021复制代码类型:[java]

  第三步:创建简单工厂

/**
 * 第三步:创建简单工厂类,负责创建用户所需的对象
 */
public class SimplePayFactory {

    /**
     * 获取支付对象方法
     * @param beanName
     * @return
     */
    public static IPay getPayInstance(String beanName) {
        if (beanName.equalsIgnoreCase("AliPay")) {
            return new AliPay();
        } else if (beanName.equalsIgnoreCase("WechatPay")) {
            return new WechatPay();
        } else {
            return null;
        }
    }
}1234567891011121314151617181920复制代码类型:[java]

  第四步:测试

public class SimpleFactoryTest {

    public static void main(String[] args) {
        IPay aliPay = SimplePayFactory.getPayInstance("AliPay");
        aliPay.unifiedorder();
        IPay wechatPay = SimplePayFactory.getPayInstance("WechatPay");
        wechatPay.unifiedorder();
    }
}123456789复制代码类型:[java]

  运行结果:

调用阿里支付
调用微信支付12复制代码类型:[java]

  优点:解耦

  缺点:

  违背开闭原则,新增Product类需要修改 getPayInstance 代码

  一定程度上增加了类的数量

  不利于系统的维护和扩展

  工厂方法(Factory Method)

  工厂方法模式又称工厂模式,是简单工厂的一个变种,解决了开闭原则问题。用户只需要知道具体工厂的名称就可以拿到相应的对象。如下图所示:

  还是以支付为例,在工厂方法中,原有内容保持不变,但多了一层获取具体工厂的接口。

  第一步:创建支付接口

**
 * 第一步:创建抽象产品接口,定义抽象方法,让具体的产品类去实现具体业务
 */
public interface IPay {

    /**
     * 定义统一支付方法
     */
    void unifiedorder();
}12345678910复制代码类型:[java]

  第二步:创建具体的业务实现

/**
 * 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
 */
public class AliPay implements IPay {

    @Override
    public void unifiedorder() {
        System.out.println("调用阿里支付");
    }
}

/**
 * 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
 */
public class WechatPay implements IPay{

    @Override
    public void unifiedorder() {
        System.out.println("调用微信支付");
    }
}123456789101112131415161718192021复制代码类型:[java]

  第三步:创建获取支付对象的工厂

/**
 * 第三步:抽象工厂类,用于描述具体工厂的公共接口
 */
public interface IPayFactory {

    /**
     * 具体工厂的抽象方法
     * @return IPay
     */
    IPay getPay();
}1234567891011复制代码类型:[java]

  第四步:创建具体工厂类

/**
 * 第四步:具体工厂类,实现抽象工厂接口,完成对象创建
 */
public class AlipayFactory implements IPayFactory{

    @Override
    public IPay getPay() {
        return new AliPay();
    }
}

/**
 * 第四步:具体工厂类,实现抽象工厂接口,完成对象创建
 */
public class WechatFactory implements IPayFactory{

    @Override
    public IPay getPay() {
        return new WechatPay();
    }
}123456789101112131415161718192021复制代码类型:[java]

  第五步:测试

public class MethodFactoryTest {

    public static void main(String[] args) {
        IPayFactory alipayFactory = new AlipayFactory();
        IPay aliPay = alipayFactory.getPay();
        aliPay.unifiedorder();
        IPayFactory wechatFactory = new WechatFactory();
        IPay wechatPay = wechatFactory.getPay();
        wechatPay.unifiedorder();
    }
}
123456789101112复制代码类型:[java]

  运行结果:

调用阿里支付
调用微信支付12复制代码类型:[java]

  优点:

  解耦

  符合开闭原则

  提高了扩展性和复用性

  缺点:

  类数量过多,工厂越多复杂性越高

  更具抽象性,增加了理解成本

  抽象产品接口只能生产一种产品

  抽象工厂(Abstract Factory)

  通过工厂方法的学习,大家也可以感觉到该模式只考虑同类型的产品,但是生活中同样有很多综合型的工厂,如大学有很多的专业,企业里有很多的岗位等等,这就造就了抽象工厂模式。

  为了更好的理解抽象工厂,我们先来了解下产品的相关概念,如下图所示:

  简单工厂模式不建议在产品种类多的情况下使用

  接下来就以苹果和华为公司生产电脑和手机为例,实现抽象工厂。如下图所示:

  第一步:创建产品工厂

/**
 * 第一步:创建电脑工厂,并定义功能
 */
public interface IComputerFactory {

    /**
     * 开机
     */
    void start();

    /**
     * 关机
     */
    void stop();
}

/**
 * 第一步:创建手机工厂,并定义功能
 */
public interface IPhoneFactory {

    /**
     * 开机
     */
    void start();

    /**
     * 关机
     */
    void stop();
}12345678910111213141516171819202122232425262728293031复制代码类型:[java]

  第二步:创建具体产品

  创建苹果产品: 

/**
 * 第二步:创建具体产品(苹果电脑)
 */
public class Mac implements IComputerFactory{
    @Override
    public void start() {
        System.out.println("苹果电脑开机");
    }

    @Override
    public void stop() {
        System.out.println("苹果电脑关机");
    }
}

/**
 * 第二步:创建具体产品(苹果手机)
 */
public class IPhone implements IPhoneFactory{

    @Override
    public void start() {
        System.out.println("苹果手机开机");
    }

    @Override
    public void stop() {
        System.out.println("苹果手机关机");
    }
}123456789101112131415161718192021222324252627282930复制代码类型:[java]

  创建华为产品:

/**
 * 第二步:创建具体产品(华为电脑)
 */
public class HuaWeiComputer implements IComputerFactory{
    @Override
    public void start() {
        System.out.println("华为电脑开机");
    }

    @Override
    public void stop() {
        System.out.println("华为电脑关机");
    }
}

/**
 * 第二步:创建具体产品(华为手机)
 */
public class HuaWeiPhone implements IPhoneFactory{

    @Override
    public void start() {
        System.out.println("华为手机开机");
    }

    @Override
    public void stop() {
        System.out.println("华为手机关机");
    }
}123456789101112131415161718192021222324252627282930复制代码类型:[java]

  第三步:创建企业工厂

/**
 * 第三步:创建企业工厂(苹果工厂)
 */
public class AppleFactory implements IProductFactory{

    @Override
    public IPhoneFactory phoneProduct() {
        return new IPhone();
    }

    @Override
    public IComputerFactory computerProduct() {
        return new Mac();
    }
}

/**
 * 第三步:创建企业工厂(华为工厂)
 */
public class HuaWeiFactory implements IProductFactory{

    @Override
    public IPhoneFactory phoneProduct() {
        return new HuaWeiPhone();
    }

    @Override
    public IComputerFactory computerProduct() {
        return new HuaWeiComputer();
    }
}12345678910111213141516171819202122232425262728293031复制代码类型:[java]

  第四步:创建最上层抽象工厂

/**
 * 第四步:创建最上层抽象工厂
 */
public interface IProductFactory {

    /**
     * 生产手机
     * @return IPhoneFactory
     */
    IPhoneFactory phoneProduct();

    /**
     * 生产电脑
     * @return IComputerFactory
     */
    IComputerFactory computerProduct();
}1234567891011121314151617复制代码类型:[java]

  第五步:抽象工厂测试

public class AbstractFactoryTest {

    public static void main(String[] args) {
        // 苹果产品系列
        IProductFactory appleFactory = new AppleFactory();
        IComputerFactory appleComputerFactory = appleFactory.computerProduct();
        appleComputerFactory.start();
        appleComputerFactory.stop();
        IPhoneFactory applePhoneFactory = appleFactory.phoneProduct();
        applePhoneFactory.start();
        applePhoneFactory.stop();
        System.out.println("======================");
        // 华为产品系列
        IProductFactory huaWeiFactory = new HuaWeiFactory();
        IComputerFactory huaWeiComputerFactory = huaWeiFactory.computerProduct();
        huaWeiComputerFactory.start();
        huaWeiComputerFactory.stop();
        IPhoneFactory huaWeiPhoneFactory = huaWeiFactory.phoneProduct();
        huaWeiPhoneFactory.start();
        huaWeiPhoneFactory.stop();
    }
}12345678910111213141516171819202122复制代码类型:[java]

  运行结果:

苹果电脑开机
苹果电脑关机
苹果手机开机
苹果手机关机
====分割线====
华为电脑开机
华为电脑关机
华为手机开机
华为手机关机123456789复制代码类型:[java]

  优点:工厂方法的扩展,实现了产品族生产。

  缺点:

  不是很符合开闭原则

  产品族扩展困难

  比工厂方法更抽象,理解更困难

  总结

  通过本篇文章的学习,总结以下几点:

  简单工厂模式不建议在产品种类多的情况下使用

  工厂方法模式适用于多种厂家生产类似产品,项目中使用频率较低

  抽象工厂是工厂方法的扩展,实现了产品族生产

  抽象工厂在实际开发中的出现的频率更低

  抽象工厂中每个工厂只生产一个产品时建议使用工厂方法




是工厂方法的扩展,实现了产品族生产

  抽象工厂在实际开发中的出现的频率更低

  抽象工厂中每个工厂只生产一个产品时建议使用工厂方法



网站内容来自网络,如有侵权请联系我们,立即删除!
Copyright © 晒百科 鲁ICP备2024098781号-3