常用设计模式——深入理解工厂模式

工厂模式
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式 在设计模式当时它属于创建性模式 而它却又分成了简单工厂模式、工厂方法模式、抽象工厂模式。


场景:
在开发过程中想必大家都对接过支付接口,而在选择支付方式的时候常常有很多种,如银联、支付宝 等,在随着系统逐渐运行,假如我们现在需要添加微信支付,而在这时我们怎么应对系统扩展呢?



一:简单工厂

定义:简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现


上代码:
我们先创建一个支付接口,接着创建支付宝支付,微信支付 代码如下:

支付接口:

package com.designpattern.factory;

/**
 * 支付接口
 * zhan_lang
 */
public interface Pay {

    void create();

}

支付宝支付:

package com.designpattern.factory;

/**
 * 支付宝支付
 * zhan_lang
 */
public class AliPay implements Pay {


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


}

微信支付:

package com.designpattern.factory;

/**
 * 微信支付
 * zhan_lang
 */
public class Wechat implements Pay {

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


}

现在我们支付方式有了 那么我们怎么来获取支付方式呢?在这里简单工厂只需要获取对象实例即可,代码实现如下:

package com.designpattern.factory.simple;

import com.designpattern.factory.AliPay;
import com.designpattern.factory.Pay;
import com.designpattern.factory.Wechat;
import org.springframework.util.StringUtils;

/**
 * zhan_lang
 * 简单工厂创建类
 */
public class PayFactory {


    /**
     * 简单方式
     * @param name
     * @return
     */
    public Pay create(String name){

        if ("wechat".equals(name)){
            return new Wechat();
        }else if ("alipay".equals(name)){
            return new AliPay();
        }
        return null;

    }

    /**
     * className 方式
     * @param s
     */
    public Pay createByClassName(String s)  {

        try {
            if (!StringUtils.isEmpty(s)){
                return (Pay) Class.forName(s).newInstance();
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return null;
    }


    /**
     * clazz
     * @param clazz
     */
    public Pay createByClazz(Class<?> clazz) {
        try {
            if (clazz != null){
                return (Pay) clazz.newInstance();
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return null;
    }
}

获取对象实例写好了 我们来调用一波,

package com.designpattern.factory.simple;

import com.designpattern.factory.AliPay;
import com.designpattern.factory.Pay;
import com.designpattern.factory.Wechat;

/**
 * 简单工厂
 *  优点:只需要传入一个正常的参数则可以获取一个实例 无需关注创建过程
 *  缺点:创建过程简单 不易于扩展 如果新增工厂类 需要修改判断 违背了开闭原则
 * zhan_lang
 */
public class PayTest {


    public static void main(String[] args) {

        //未用工厂
        Pay pay = new Wechat();
        pay.create();

        //最原始方式(必须传入正常字符串判断)
        PayFactory payFactory = new PayFactory();
        payFactory.create("alipay").create();

        //ClassName 必须传入正常包点类名
        PayFactory payFactory1 = new PayFactory();
        payFactory1.createByClassName("com.designpattern.factory.AliPay").create();


        //calzz 传入已有类
        PayFactory payFactory2 = new PayFactory();
        payFactory2.createByClazz(AliPay.class).create();


    }

}

简单工厂模式就是如此简单 只需要提供创建对象实例的方法就可以了 但是这里请注意 我们在判断获取哪个对象实例的时候 如果还是用if-else-if 来判断是不是有点说不过去了(太low了 有100种实例 你会判断100次吗 反正我不会) 所以我们改用以反射的方式来获取对象实例。
至于简单工厂模式的优缺点 在调用的时候已经写出来 这里就不在啰嗦了。

二:工厂方法模式

定义:工厂方法模式使用的频率非常高,在我们日常开发中总是能看到它的影子,其定义为:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。

上代码:
这里我们还是运用支付方式来跟大家讲解 对象实例还是运用简单工厂模式里面的实例 但是我们这里需要单独创建一个工厂接口 抽象出一个支付接口 然后支付方式去实现工厂接口 这样我们创建类的实例就可以延迟到子类了。代码如下:

工厂接口:

package com.designpattern.factory.factory;

import com.designpattern.factory.Pay;

/**
 * 工厂接口
 * zhan_lang
 */
public interface PayFactory {

    //如果工厂类需要自己的业务逻辑处理 则可以将接口改成抽象类来保留

    Pay create();

}

创建对象实例:在这里我们就这个类实例化过程交给了子类了

package com.designpattern.factory.factory;

import com.designpattern.factory.AliPay;
import com.designpattern.factory.Pay;

/**
 * zhan_lang
 */
public class AliPayFactory implements PayFactory {


    @Override
    public Pay create() {
        return new AliPay();
    }


}

老规矩调用一波:

package com.designpattern.factory.factory;

import com.designpattern.factory.Pay;

/**
 * 工厂方法模式
 * 优点:没有违背开闭原则 提高了扩展性 类过多(新增则需要添加工厂类和基类)
 * 缺点:增加了系统的抽象性和理解难度
 * zhan_lang
 */
public class PayTest {

    public static void main(String[] args) {
        PayFactory payFactory = new AliPayFactory();
        Pay pay = payFactory.create();
        pay.create();

    }

}

这样工厂方法模式就完成了 但是需要注意的是 工厂接口不仅仅只能是接口类型 如果它有自己的业务逻辑 则可以将接口改成抽象类 这里我们就不演示代码了

三:抽象工厂模式

在简单工厂和工厂方法模式当中 支付方式是出来了 在一个传统的支付当中 光有支付怎么行 我们的支付记录呢 那这种情况我们又该怎么办呢?请看抽象工厂模式

定义:抽象工厂模式(Abastract Factory Pattern)是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类
上代码:
这里我们先创建工厂接口 并提供支付和支付记录两个接口

package com.designpattern.factory.abstractfactory;

/**
 * 抽象顶层接口
 * 在真实的支付场景中 我们是不光只有支付过程的  我们还有支付记录 对于这样一个系列多个产品的场景我们怎么来处理呢?
 * zhan_lang
 */
public interface PayFactory {

    IPay createPay();

    IPayRecord createRecord();

}

然后创建支付接口并提供方法

package com.designpattern.factory.abstractfactory;

/**
 * 支付
 * zhan_lang
 */
public interface IPay {

    void createPay();

}
package com.designpattern.factory.abstractfactory;

/**
 * 创建支付宝支付
 * zhan_lang
 */
public class AliPay implements  IPay {


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

}

创建支付记录接口并提供方法

package com.designpattern.factory.abstractfactory;

/**
 * 支付记录
 * zhan_lang
 */
public interface IPayRecord {


    void createRecord();

}

package com.designpattern.factory.abstractfactory;

/**
 * 产生支付记录
 * zhan_lang
 */
public class AliPayRecord implements  IPayRecord {


    @Override
    public void createRecord() {
        System.out.println("产生支付记录");
    }
}

创建支付宝工厂类 并提供支付和支付记录方法

package com.designpattern.factory.abstractfactory;

/**
 * 支付宝工厂
 */
public class AliPayFactory implements  PayFactory {


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

    @Override
    public IPayRecord createRecord() {
        return new AliPayRecord();
    }


}

最后调用一波

package com.designpattern.factory.abstractfactory;

/**
 * 抽象工厂模式
 * 优点:将一个系列的多个产品一起创建
 * 缺点:增加了系统的抽象性和理解难度 扩展新的产品比较困难 需要修改抽象工厂接口
 * zhan_lang
 */
public class AbstractFactoryTest {


    public static void main(String[] args) {
        PayFactory payFactory = new AliPayFactory();
        payFactory.createPay().createPay();
        payFactory.createRecord().createRecord();
    }

}

完美实现 有没有 ?这里同工厂方法模式一样 如果工厂接口有其他业务逻辑 可以换成抽象类来实现
最后将类图提供给大家 方便大家理解 在idea当中 显示类图快捷键为:ctrl+Shift+Alt+U
在这里插入图片描述

在这里工厂方法模式就介绍完了 你了解了吗?
最后,最后提醒大家 要学以致用 这样才不会忘 才能写出更高逼格的代码 !

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值