Java工厂模式应用
1.1 案例需求
假设对于学校使用仪器要进行网上收费,然后学校可根据不同主体,比如课题组或者个人进行收费。也具有不同的收费模式。那么对于原先的代码来说需要进行多个if-else判断,代码示例如下:
public void chargeBackAndReturnResult(String chargeType,String chargeBody) {
if(chargeBody.equals("Personal")){
if(chargeType.equals("Credit")){
System.out.println("执行收费主体为个人的信用卡收费模式");//真实业务代码有200行左右
}else if(chargeType.equals(" deposit")){
System.out.println("执行收费主体为个人的储蓄卡收费模式");
}
}else if(chargeBody.equals("CommonTeam")){
if(chargeType.equals("Credit")){
System.out.println("执行收费主体为课题组的信用卡收费模式");
}else if(chargeType.equals(" deposit")){
System.out.println("执行收费主体为课题组的储蓄卡收费模式");
}
}
}
对于这种if-else嵌套来说,即使进行方法的封装,依然不利于程序扩展,并且如果增加收费主体和收费类型,则需要继续增加if-else嵌套,影响代码的可读性。
1.2 优化方案
可以明确的是,对于不同的收费主体以及收费模式,所传入的参数基本相同。无外乎用户/课题组编号,金额等基本业务内容。那么我们就可以将收费模式统一抽象出一种行为规范作为接口,并通过不同实现类对接口进行继承。然后通过工厂进行统一管理,这就是工厂模式的核心思想。
1.2.1 接口的创建
public interface ChargeService {
String getType();//用于获取收费类型
String chargeBackAndReturnResult();//用于执行具体收费方法
}
1.2.2 实现类的创建
public class DepositPersonalChargeServiceImpl implements ChargeService{
public String getType(){
return "DepositPersonal";
}
public void chargeBackAndReturnResult() {
System.out.println("执行收费主体为个人的借记卡收费模式");
}
}
public class DepositCommonTeamChargeServiceImpl implements ChargeService{
public String getType(){
return "DepositCommonTeam";
}
public void chargeBackAndReturnResult() {
System.out.println("执行收费主体为课题组的借记卡收费模式");
}
}
public class CreditPersonalChargeServiceImpl implements ChargeService{
public String getType(){
return "CreditPersonal";
}
public void chargeBackAndReturnResult() {
System.out.println("执行收费主体为个人的信用卡收费模式");
}
}
public class CreditCommonTeamChargeServiceImpl implements ChargeService{
public String getType(){
return "CreditCommonTeam";
}
public void chargeBackAndReturnResult() {
System.out.println("执行收费主体为课题组的信用卡收费模式");
}
}
1.2.3 工厂的创建
public class ChargeFactory{
public static Map<String,ChargeService> chargeMap=new HashMap<String,ChargeService>();//定义一个map容器
static{
chargeMap.put("DepositCommonTeam",new DepositCommonTeamChargeServiceImpl());
chargeMap.put("DepositPersonal",new DepositPersonalChargeServiceImpl());
chargeMap.put("CreditPersonal",new CreditPersonalChargeServiceImpl());
chargeMap.put("CreditCommonTeam",new CreditCommonTeamChargeServiceImpl());
}//写入map的值
public static ChargeService getChargeService(String chargeType){
ChargeService chargeService=chargeMap.get(chargeType);
if(chargeService!=null){
return chargeService;
}else{
return null;
}
}
}
1.2.4 测试用例
public static void main(String[] args){
ChargeService chargeService=ChargeFactory.getChargeService("DepositCommonTeam");//获取对应的Service对象
chargeService.chargeBackAndReturnResult();//调用对应的方法
}
输出结果
执行收费主体为课题组的借记卡收费模式
2 利用SpringBoot框架进行进一步优化
2.1 之前方案所存在的不足
对于案例给出的解决方案来说,存在两个缺点:
新策略添加时,不仅需要增添新的class类,还需要在Factory工厂进行对应class的添加。
参照mvc经典框架下实现代码:
//Service实现层
@Service
public class DepositCommonTeamChargeServiceImpl implements ChargeService{
@Autowired
UserService userService;
public String getType(){
return "DepositCommonTeam";
}
public void chargeBackAndReturnResult() {
if(userService==null){
System.out.println("User服务注入失败");
}else{
System.out.println("User服务注入成功");
}
System.out.println("执行收费主体为课题组的借记卡收费模式");
}
}
//Controller层
@RestController
public class Test {
@RequestMapping(value = "/charge/test",method = RequestMethod.POST)
public void test(){//经典mvc框架Controller层调用Service方法
ChargeService chargeService=ChargeFactory.getChargeService("DepositCommonTeam");
chargeService.chargeBackAndReturnResult();
}
}
输出结果
User服务注入失败
执行收费主体为课题组的借记卡收费模式
能够发现如果应用@Autowired注解所注入的Spring对象,在方法调用时无法获取到。
2.2 优化解决方案
修改原Factory工厂类
@Component
public class ChargeFactory implements ApplicationContextAware {
public static Map<String,ChargeService> chargeMap=new HashMap<String,ChargeService>();//定义一个Map类
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//根据接口类型返回相应的所有bean
Map<String, ChargeService> map = applicationContext.getBeansOfType(ChargeService.class);//通过applicationContext获取注入Spring容器中的类
map.forEach((key, value) -> chargeMap.put(value.getType(), value));//给Map类进行赋值
}
public static ChargeService getChargeService(String chargeType){
ChargeService chargeService=chargeMap.get(chargeType);
if(chargeService!=null){
return chargeService;
}else{
return null;
}
}
}
此时再进行结果输出
User服务注入成功
执行收费主体为课题组的借记卡收费模式
I can feel you forgetting me。。 有一种默契叫做我不理你,你就不理我