目录
说明
实现方式
简单工厂模式
工厂方法模式
说明
- 五大创建型模式之一,其他还有单例模式、抽象工厂模式、原型模式、建造者模式
- 简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,是工厂模式家族中最简单实用的模式
- 当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式
- 工厂模式(Factory Pattern)的意义在于:将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性
实现方式
目前我们出门购物,付钱的时候基本都是让商家扫支付宝二维码或者微信二维码,但是我们总得先打开相应软件,再点付款码。能不能使用一款App,自由选择支付码类型呢?那就可以用下面的简单工厂来实现啦。UML和代码:
/**
* 简单工厂
*
* @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,还需要在单一的工厂类添加实例化该支付码类的判断。这种缺陷,可用下述的工厂方法模式解决:
/**
* 工厂方法模式(一个工厂生产一种产品,多种产品则需要能有多个工厂)
* 不足:工厂功能过于单一,再要新产品,则需要再添加工厂。
*
* @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. 添加新产品时无需修改已有代码。但其工厂类功能过于单一,不能满足工厂类多功能的需求。当然可以用抽象工厂模式进行解决。