设计模式之简单工厂模式

目录

1、简介

2、特点

3、代码演示

3.1、类图

3.2、代码

3.2.1、PayService

3.2.2、AliPayService

3.2.3、WeiXinPayService

3.2.4、PayServiceFactory

3.2.5、Store

4、优缺点

4.1、优点

4.2、缺点

4.3、如何去解决简单工厂的问题呢?

AliPayService

WeiXinPayService

PayServiceFactory

使用环境


1、简介

        简单工厂模式(Simple Factory)又称为静态工厂方法模式(Static Factory Method)。简单工厂模式简单来说就是根据参数的不同返回不同类的实例。


2、特点

  • 简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

3、代码演示

3.1、类图

3.2、代码

3.2.1、PayService

package com.inconspicuousy.pattern.simplefactory;

/**
 * 支付基类
 * @author inconspicuousy
 */
public interface PayService {

    /** 支付 */
    void doPay();

}

3.2.2、AliPayService

package com.inconspicuousy.pattern.simplefactory;

/**
 * 支付宝支付
 * @author inconspicuousy
 */
public class AliPayService implements PayService {

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

3.2.3、WeiXinPayService

package com.inconspicuousy.pattern.simplefactory;

/**
 * 微信支付
 * @author inconspicuousy
 */
public class WeiXinPayService implements PayService {

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

3.2.4、PayServiceFactory

package com.inconspicuousy.pattern.simplefactory;

/**
 * 提供简单支付工厂类, 为用户选择指定的支付方式
 *
 * 简单工厂又叫静态工厂
 * @author inconspicuousy
 */
public class PayServiceFactory {

    /**
     * 根据二维码链接获取到实际的支付方式
     *
     * 什么是简单工厂模式?
     * 实际上就是根据用户的某个行为创建指定的对象,
     * 将创建对象的方式作集中处理, 每次如果要对支付方式扩展,只需要针对简单工厂类进行修改,
     * 调用者不需要做修改, 符合OCP原则
     *
     * @param qrCodeUrl 用户选择的支付方式, 用来区分支付宝还是微信
     * @return 返回实际的支付方式
     */
    public static PayService getPayService(String qrCodeUrl) {

        if (qrCodeUrl.startsWith("alipay")) {
            return new AliPayService();
        }

        if (qrCodeUrl.startsWith("weixin")) {
            return new WeiXinPayService();
        }

        System.out.println("当前没有可用的支付方式");

        return null;
    }


}

3.2.5、Store

package com.inconspicuousy.pattern.simplefactory;

/**
 * 店铺就是当前的客户端, 用来为用户提供二维码链接
 *
 * 测试简单工厂
 * @author inconspicuousy
 */
public class Store {

    public static void main(String[] args) {

        String qrCodeUrl = "alipay://xxx";
        // 所有的店铺都只是通过二维码获取到支付方式
       // 当需要扩展支付方式时时不需要商店作出改变, 改变简单工厂就行
        PayService payService = PayServiceFactory.getPayService(qrCodeUrl);
        if (payService != null) {
            // 使用支付宝支付
            payService.doPay();
        }
    }

}

4、优缺点

4.1、优点

   简单易于实现,把类的实例化交给工厂,易于解耦  

4.2、缺点

违反开闭原则,不利于扩展和维护(没增加一个支付方式就需要修改工厂的方法)

4.3、如何去解决简单工厂的问题呢?

  1. 将对象的名称和对象通过配置文件(xml)进行配置,读取到内存中建立映射关系(Map集合,注意:使用修改配置文件不算违反开闭原则,配置文件不需要编译)
  2. 直接在工厂类中加一个map集合,key为bean名称,value是bean对象,最后加一个从map集合中获取bean的方法,并且在启动时就将所有实现类的bean对象加载到map集合中

这里使用解决方案二演示:

接口:

package com.kgf.factory.simple.inter;
 
/**
 * 支付基类
 * @author inconspicuousy
 */
public interface PayService {
 
    /** 支付 */
    void doPay();
 
}

AliPayService

package com.kgf.factory.simple.inter.impl;

import com.kgf.factory.simple.inter.PayService;
import org.springframework.stereotype.Service;

/**
 * 支付宝支付
 * @author inconspicuousy
 */
@Service
public class AliPayService implements PayService {
 
    @Override
    public void doPay() {
        System.out.println("使用支付宝支付");
    }
}
 

WeiXinPayService

package com.kgf.factory.simple.inter.impl;

import com.kgf.factory.simple.inter.PayService;
import org.springframework.stereotype.Service;

/**
 * 微信支付
 * @author inconspicuousy
 */
@Service
public class WeiXinPayService implements PayService {
 
    @Override
    public void doPay() {
        System.out.println("使用微信支付");
    }
}
 

PayServiceFactory

package com.kgf.factory.simple.factory;

import com.kgf.factory.simple.inter.PayService;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 提供简单支付工厂类, 为用户选择指定的支付方式
 *
 * 简单工厂又叫静态工厂
 * @author inconspicuousy
 */
@Component
public class PayServiceFactory implements ApplicationContextAware {

    private static Map<String,PayService> payServiceMap;

    /***
     * 直接将所有实现PayService的实现类对象获取
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.payServiceMap = applicationContext.getBeansOfType(PayService.class);
    }

    /**
     * 根据二维码链接获取到实际的支付方式
     *
     * 什么是简单工厂模式?
     * 实际上就是根据用户的某个行为创建指定的对象,
     * 将创建对象的方式作集中处理, 每次如果要对支付方式扩展,只需要针对简单工厂类进行修改,
     * 调用者不需要做修改, 符合OCP原则
     *
     * @param beanName 用户选择的支付方式的bean对象名称,用来区分支付宝还是微信
     * @return 返回实际的支付方式
     */
    public static PayService getPayService(String beanName) {
        PayService payService = payServiceMap.get(beanName);
        if (payService!=null){
            return payService;
        }
        System.out.println("当前没有可用的支付方式");
        return null;
    }

}

测试代码:

package com.kgf.factory.simple;

import com.kgf.factory.FactoryApplication;
import com.kgf.factory.simple.factory.PayServiceFactory;
import com.kgf.factory.simple.inter.PayService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = FactoryApplication.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FactoryPatternTest {

    @Test
    public void SimpleFactoryTest(){
        PayService payService = PayServiceFactory.getPayService("aliPayService");
        if (payService != null) {
            // 使用支付宝支付
            payService.doPay();
        }
    }
}

效果:

使用环境

  • 工厂类负责创建的对象比较少的情况适合使用。创建的对象较少,不会造成工厂方法中业务逻辑太过复杂。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值