1.好久没写博客了,竟然有人给我点赞和关注我。在这里结合最近工作做用的设计模式 分享一下简单工厂模式+策略模式在工作中的实际运用。场景可能如下:假设我们要写一个放款的接口,对接的资金方有华夏银行、晋中银行、南京银行等资金方。每个资金方放款的流程、实现的逻辑、上送的参数等可能不相同,但在我们业务的主体类放款逻辑是一样的,只是放款的实现不同而已。通常的做法是使用if(南京银行) 写南京银行的业务逻辑 else if(晋中银行) 写晋中银行的业务逻辑。虽然在这里也可以实现相应的功能,但代码显得很臃肿、复杂,太多的if else 逻辑判断 耦合性太强。此时我们可以使用简单工厂+策略模式 将if else 进行剥离。具体实现如下。
package com.daidaia.serivce.impl;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.daidaia.serivce.IConsumerService;
/**
* 包装类 这里可以看成 简单的工厂模式 + 策略模式(子类的具体实现逻辑不一样)
* 包装IConsumerService 接口所有的实现类
* 所有实现IConsumerService 接口的类 可以看做策略模式 每个子类具体的业务逻辑不一样
* 约束 所有实现IConsumerService 接口的实现类 bean的名字取名为 type(业务类型名) + IConsumerService.class.getSimpleName().substring(1)
* 或者定义一个Map做相关的关系映射
*
* @author 呆呆啊
* @since 2019-04-24 23:25
* {@link 1721995310@qq.com}
*
*/
@Component
public class MqMessageWrapper {
@Autowired
private Map<String,IConsumerService> factory ; // 注入IConsumerService接口所有的实现类 key 为bean 的名字
/**存放业务类型和对应的具体接口实现的beanName**/
private static final Map<String,String> businessCode = new HashMap<String, String>() ;
@PostConstruct
public void init() {
businessCode.put("businecode", "optOtherService") ;
}
public void handlMessage(String type , String mesg) {
System.out.println("map="+factory);
System.out.println(String.format("MqMessageWrapper type=%s mesg=%s", type,mesg));
IConsumerService consumerService = getInstance(type) ;
if(consumerService == null) {
System.out.println("找不到对应的服务类="+type);
return ;
}
consumerService.handlMessage(mesg);
}
/**
* 产生一个IConsumerService接口的实现类
* @param type
* @return
*/
public IConsumerService getInstance(String type) {
String consumerServiceName = businessCode.get(type) ;
if(StringUtils.isEmpty(consumerServiceName)) {
consumerServiceName = type + IConsumerService.class.getSimpleName().substring(1) ;
}
IConsumerService consumerService = factory.get(consumerServiceName) ;
return consumerService ;
}
}
package com.daidaia.serivce;
public interface IConsumerService {
/**
* 处理消息服务接口
* @param mesg
*/
void handlMessage(String mesg) ;
}
package com.daidaia.serivce.impl;
import org.springframework.stereotype.Service;
import com.daidaia.serivce.IConsumerService;
/**
* 邮件消息服务处理方式
* @author 呆呆啊
* @since 2019-04-24 23:25
* {@link 1721995310@qq.com}
*
*/
@Service("emailConsumerService")
public class OptEmailConsumerServiceImpl implements IConsumerService {
public void handlMessage(String mesg) {
System.out.println("emailConsumerService mesg="+mesg);
}
}
package com.daidaia.serivce.impl;
import org.springframework.stereotype.Service;
import com.daidaia.serivce.IConsumerService;
/**
* 其他业务消息处理方式
* @author 呆呆啊
* @since 2019-04-24 23:25
* {@link 1721995310@qq.com}
*
*/
@Service("optOtherService")
public class OptOtherServiceImpl implements IConsumerService {
public void handlMessage(String mesg) {
System.out.println("SmsConsumerService mesg="+mesg);
}
}
package com.daidaia.serivce.impl;
import org.springframework.stereotype.Service;
import com.daidaia.serivce.IConsumerService;
/**
* 短信消息服务的处理方式
* @author 呆呆啊
* @since 2019-04-24 23:25
* {@link 1721995310@qq.com}
*
*/
@Service("smsConsumerService")
public class OptSmsConsumerServiceImpl implements IConsumerService {
public void handlMessage(String mesg) {
System.out.println("SmsConsumerService mesg="+mesg);
}
}
package com.daidaia.bean;
import java.util.Random;
import java.util.Scanner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.daidaia.bean.pojo.Person;
import com.daidaia.serivce.impl.MqMessageWrapper;
//import org.springframework.context.ApplicationContext;
//import org.springframework.context.annotation.AnnotationConfigApplicationContext;
//
//import com.daidaia.bean.pojo.Person;
public class MainTestBean {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext("com.daidaia") ;
Person person = context.getBean(Person.class) ;
System.out.println(person);
String[] beanNames = context.getBeanNamesForType(Person.class) ;
for(String beanName : beanNames) {
System.out.println(beanName);
}
MqMessageWrapper wrapper = context.getBean(MqMessageWrapper.class) ;
wrapper.handlMessage("sms", "sms 约束命名规范");
wrapper.handlMessage("email", "email 约束命名规范");
wrapper.handlMessage("businecode", "businecode和optOtherService 映射业务和服务实现类之间的关系");
}
}
2.如果对你有帮助,记得帮我点个赞。后续将代码放到github