Osheep

时光不回头,当下最重要。

设计模式-简单工厂模式

工厂模式一共分为三种,简单工厂、工厂模式和抽象工厂。这三种工厂模式都属于创建型模式。这篇博文主要讲解工厂模式的第一种-简单工厂模式。

介绍

简单工厂模式(Simple Factory Pattern)又称为静态工厂方法(Static Factory Method)模式,它可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
说的简单点,就是把对象的创建转移到另一个类中,通过传入不同的参数获得不同的对象,spring中注入实体也可以看做是工厂模式,因为可以通过修改不同的bean名字获得不同的对象。
其实博主上一篇的设计模式-外观模式也可用采用工厂来获得不同的对象。

优点

工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

缺点

由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

案例

这边就采用支付的案例进行讲解,用户在选择商品后进行付款,那么付款方式现如今多种多样,有支付宝、微信、银联等等。这就是一个可以采用工厂模式的例子。

支付抽象类

public abstract class Pay {
    public void init(){
        System.out.println("支付方式初始化");
    }
    
    public abstract void orderPay();
}

支付宝支付类

public class AliPay extends Pay {

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

}

微信支付类

public class WechatPay extends Pay {

    @Override
    public void orderPay() {
        System.out.println("微信支付");
    }

}

银联支付类

public class UnionPay extends Pay {

    @Override
    public void orderPay() {
        System.out.println("银联支付");
    }

}

简单工厂类
choicePay也可以不用静态,根据具体情况使用

public class PayFactory {
    public static Pay choicePay(String payMethod){
        Pay pay = null;
        if ("aliPay".equals(payMethod)) {
            pay = new AliPay();
        } else if ("wechatPay".equals(payMethod)) {
            pay = new WechatPay();
        } else if ("unionPay".equals(payMethod)) {
            pay = new UnionPay();
        }
        
        return pay;
    }
    
    public static void main(String[] args) {
        String payMethod = "aliPay";
        Pay pay = PayFactory.choicePay(payMethod);
        if (pay != null) {
            pay.init();
            pay.orderPay();
        } else {
            System.out.println("未选择支付方式");
        }
        
    }
}

具体代码见Github地址

总结

简单工厂将对象的实例化抽取出来,可以降低系统的耦合度,使得两者修改起来都相对容易。在调用工厂类的工厂方法时,由于工厂方法是静态方法,使用起来很方便,可通过类名直接调用,而且只需要传入一个简单的参数即可,在实际开发中,还可以在调用时将所传入的参数保存在XML等格式的配置文件中,修改参数时无须修改任何源代码。
但是这样不符合开闭原则,如果增加一种支付方式,那么工厂方法便需要更改,这样也就对修改也开放了。

jdk中也有许多用到简单工厂模式的地方 Integer.valueOf()、DateFormat.getDateInstance()等等。。。

点赞