目录

 

说明

实现方式

简单工厂模式

工厂方法模式


说明

  • 五大创建型模式之一,其他还有单例模式、抽象工厂模式、原型模式、建造者模式
  • 简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,是工厂模式家族中最简单实用的模式
  • 当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式 
  • 工厂模式(Factory Pattern)的意义在于:将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性

实现方式

目前我们出门购物,付钱的时候基本都是让商家扫支付宝二维码或者微信二维码,但是我们总得先打开相应软件,再点付款码。能不能使用一款App,自由选择支付码类型呢?那就可以用下面的简单工厂来实现啦。UML和代码:

android 例子 工厂模式 工厂模式app_工厂类

/**
 * 简单工厂
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/27
 */
public class SimpleFactoryTest {
    public static void main(String[] args) {
        AbstractQrCode qRCode = MyApp.generateQRCode("微信支付码");
        validateAndShow(qRCode);
        qRCode = MyApp.generateQRCode("支付宝支付码");
        validateAndShow(qRCode);
    }

    /**
     * 判断参数是否为空,不为空则调用方法(使用实例)
     * <p>
     * @author ZRH
     * @date 2020/7/20 16:18
     * @version 1.0.0
     * @param pay
     */
    private static void validateAndShow(AbstractQrCode pay) {
        if (pay == null) {
            System.out.println("未知支付方式");
        }else{
            pay.showPaymentQrCode();
        }
    }


}
/**
 * 我的支付App,可以生成微信的支付码,也可以生成支付宝的支付码(工厂类)
 * <p>       
 * @author ZRH
 * @date 2020/7/27
 * @version 1.0.0
 */
class MyApp {
    /**
     * 根据支付类型生成支付二维码(创建实例)
     * <p>
     * @author ZRH
     * @date 2020/7/20 16:19
     * @version 1.0.0
     * @param way
     * @return 支付二维码类
     */
    public static AbstractQrCode generateQRCode(String way) {
        if (way == null) {
            return null;
        }
        switch (way) {
            case "微信支付码":
                return new WeChatQrCode();
            case "支付宝支付码":
                return new AliQrCode();
            default:
                break;
        }
        return null;
    }
}

/**
 * 支付二维码
 * <p>
 *
 * @author : ZRH
 * @version : 1.0.0
 * @date : 2020/7/20 16:02
 */
abstract class AbstractQrCode {
    /**
     * 展示支付方式信息
     */
    public abstract void showPaymentQrCode();
}

/**
 * 微信支付二维码
 * <p>
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/20 16:05
 */
class WeChatQrCode extends AbstractQrCode {

    @Override
    public void showPaymentQrCode() {
        System.out.println("微信二维码");
    }
}

/**
 * 支付宝支付二维码
 * <p>
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/20 16:07
 */
class AliQrCode extends AbstractQrCode {

    @Override
    public void showPaymentQrCode() {
        System.out.println("支付宝二维码");
    }
}

 上述为简单工厂模式。可见,当有新的支付类型需要添加时,首先需要该支付码类继承AbstractQrCode,还需要在单一的工厂类添加实例化该支付码类的判断。这种缺陷,可用下述的工厂方法模式解决:

android 例子 工厂模式 工厂模式app_二维码_02

/**
 * 工厂方法模式(一个工厂生产一种产品,多种产品则需要能有多个工厂)
 * 不足:工厂功能过于单一,再要新产品,则需要再添加工厂。
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/27
 */
public class FactoryMethodTest {
    public static void main(String[] args) {
        AbstractApp app = new AliPay();
        app.generatePaymentQrCode().showQrCode();
        app = new WeChat();
        app.generatePaymentQrCode().showQrCode();
    }
}

/**
 * 一款支付的app(工厂),需要生成付款码
 * <p>
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/20 17:11
 */
abstract class AbstractApp {

    /**
     * 生成付款码
     * <p>
     *
     * @return cn.rainbow.factory.method.AbstractQrCode
     * @author : ZRH
     * @version : 1.0.0
     * @date : 2020-07-21
     */
    public abstract AbstractQrCode generatePaymentQrCode();

}

/**
 * 支付宝app(一个具体的工厂)
 */
class AliPay extends AbstractApp {

    /**
     * 生成支付宝付款码(产品)
     *
     * @return cn.rainbow.factory.method.AbstractQrCode
     */
    @Override
    public AbstractQrCode generatePaymentQrCode() {

        return new AliPaymentQrCode();
    }
}

/**
 * 微信app(一个具体的工厂)
 */
class WeChat extends AbstractApp {


    /**
     * 生成微信付款码
     * <p>
     *
     * @return cn.rainbow.factory.method.AbstractQrCode
     * @author : ZRH
     * @version : 1.0.0
     * @date : 2020-07-21
     */
    @Override
    public AbstractQrCode generatePaymentQrCode() {
        return new WeChatPaymentQrCode();
    }
}

/**
 * 二维码(产品族类)
 * <p>
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/20 17:13
 */
abstract class AbstractQrCode {
    /**
     * 显示二维码
     */
    public abstract void showQrCode();
}

/**
 * 支付宝付款码
 * <p>
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/20 17:27
 */
class AliPaymentQrCode extends AbstractQrCode {

    @Override
    public void showQrCode() {
        System.out.println("支付宝付款码");
    }
}

/**
 * 微信付款码
 * <p>
 *
 * @author ZRH
 * @version 1.0.0
 * @date 2020/7/20 17:27
 */
class WeChatPaymentQrCode extends AbstractQrCode {

    @Override
    public void showQrCode() {
        System.out.println("微信付款码");
    }
}

这样,当需要添加新类型的支付码时,只需要加个特定的工厂类以及支付码类即可(将对象的实例化推迟到子类),遵循开放封闭原则

来说说上述两种的优缺点:

简单工厂模式

1. 又叫静态工厂模式解决产品需多类型的问题

2. 其将创建实例与使用实例的工作分开,使用者不必关心类对象如何创建,实现解耦;

3. 工厂类使代码更容易维护。

4. 缺点是一旦这个工厂不能正常工作,整个系统都会受到影响;

5. 违背“开放封闭原则”,一旦添加新产品就不得不修改工厂类的逻辑。

6. 简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。

工厂方法模式

1. 添加新产品时无需修改已有代码。但其工厂类功能过于单一,不能满足工厂类多功能的需求。当然可以用抽象工厂模式进行解决