在我们工作中,尤其是电商系统中,一个庞大的电商平台不是一个封闭的平台,往往还伴生着一个开放平台,用以接入各个企业,以实现一种共赢的局面,一般来讲,针对于这种业务场景,首先浮现在开发人员脑海中的往往是工厂模式,但普通的工厂模式使用起来相对比较麻烦,而Spring则给我们提供了一种使用配置方式来扩展工厂,大大简化了我们开发的工作量,同时也做到了不同合作媒体之间的解耦。
下面我们就以一个实际的例子来说一下,比如某个电商要与百度、腾讯、淘宝等大型公司进行接入处理,而接入的功能基本上都是商品、订单、退款等大同小异的业务流程,则此时可以采用工厂模式来设计我们的功能,具体的类结构图如下:
上图是我们简化了的业务模型,其中BaseService实现了公有和基础操作,而BaiduService等则是每家媒体的具体业务实现,如果业务可以直接复用父类的功能的话则无需覆写,比如我们上面只在BaiduService中覆写了order方法。
下面展示了每个类的具体内容:
BaseService.java
package com.mhy.service;
/**
* @author mhy2011@gmail.com
* @date 2014年12月8日 下午3:10:12
*/
public class BaseService {
public void order(){
System.out.println("BaseService.order执行");
}
}
内容很简单,只有一句输出,此处只是演示,真实的合作中自然不会是这么简单的。
BaiduService.java
package com.mhy.service;
/**
* @author mhy2011@gmail.com
* @date 2014年12月8日 下午3:12:07
*/
public class BaiduService extends BaseService {
@Override
public void order() {
System.out.println("BaiduService.order执行");
}
}
TencentService.java
package com.mhy.service;
/**
*
* @author mhy2011@gmail.com
* @date 2014年12月8日 下午3:13:06
*/
public class TencentService extends BaseService {
}
TaobaoService.java
package com.mhy.service;
/**
* @author mhy2011@gmail.com
* @date 2014年12月8日 下午3:12:22
*/
public class TaobaoService extends BaseService {
}
如上所示,我们实现了一个基础类以及三个子类,用以区别不同的合作媒体。一般来讲,我们在进行第三方媒体合作时,针对于不同的合作媒体我们都会为其生成一个指定的合作名称,通过该内容我们获取到具体的媒体。Spring为我们提供了一个相应工厂类MapFactoryBean。具体的使用配置如下:
partner-bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="partnerBean" class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="targetMapClass">
<value>java.util.HashMap</value>
</property>
<property name="sourceMap">
<map>
<entry key="base" value-ref="baseService"></entry>
<entry key="baidu" value-ref="baiduService"></entry>
<entry key="tencent" value-ref="tencentService"></entry>
<entry key="taobao" value-ref="taobaoService"></entry>
</map>
</property>
</bean>
<bean id="baseService" class="com.mhy.service.BaseService"></bean>
<bean id="baiduService" class="com.mhy.service.BaiduService"></bean>
<bean id="tencentService" class="com.mhy.service.TencentService"></bean>
<bean id="taobaoService" class="com.mhy.service.TaobaoService"></bean>
</beans>
配置完之后我们来测试一下
package com.mhy.service;
import java.util.Map;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author mhy2011@gmail.com
* @date 2014年12月8日 下午3:34:51
*/
public class PartnerServiceTest {
@SuppressWarnings({ "resource", "unchecked" })
public static void main(String[] args) {
String[] partners = {"baidu", "tencent", "taobao", "qita"};
ApplicationContext ctx = new ClassPathXmlApplicationContext("partner-bean.xml");
Map<String, BaseService> map = (Map<String, BaseService>) ctx.getBean("partnerBean");
for (String partner : partners) {
BaseService service = map.get(partner);
if(null == service){
System.out.println("不存在的合作媒体.name=" + partner);
}else{
System.out.println("当前使用媒体.name=" + partner);
service.order(); //执行下单操作
}
}
}
}
然后我们来执行一下该文件,执行的结果如下:
从上面的执行结果可以看到,通过MapFactoryBean我们可以实现获取到指定实现类并执行相关的操作,大大降低了系统内的耦合性。如果后面需要增加一个媒体的话只需要增加一个该媒体的实现,然后从配置文件中配置一下即可。
好了,关于MapFactoryBean使用就说到这,如有问题欢迎大家指正。