当我们写代码时遇到了需要if else 需要实现的问题时,就可以考虑是否引入某种设计模式,能让代码写得更加graceful。
假设我们现在有个设计用户查找的RESTful接口的需求,用户可能有多个属性,有id,firstName ,lastName,age,adress 等等,我们可以这样一个接口:
http://localhost:8099/api?method=petclinic.owner.get&version=1.0&key=id&value=1&format=json
key值表示我们可以根据什么来查询,比如根据id来查询,则key为id,根据lastName来查询,则key为lastName。value则为对应的值。
接口规则设定好后,则需要进行后端controller层的编码工作了。
@ServiceMethod(value = "petclinic.owner.get", version = "1.0")
public Collection getOwner (@RequestParam String key,@RequestParam String value){
//TODO:
}
key值可以取不同的值,我们自然想到这样的处理方式。
下面是基于if else的TODO部分实现
@ServiceMethod(value = "petclinic.owner.get", version = "1.0")
public Collection getOwner (@RequestParam String key,@RequestParam String value){
//TODO:
if(key.equals("id")){
//调用业务层方法findOwnerById获取用户列表
return clinicBll.findOwnerById(value);
}else if(key.equals("lastName"){
//调用业务层方法findOwnerByLastName获取用户列表
return clinicBll.findOwnerByLastName(value);
}
}
如果用策略模式该重构代码,则我们先需要抽象一个找用户的策略(是根据id来找?还是根据lastName来找?等等)。
package com.iflytek.petclinic.service.strategy;
import com.iflytek.petclinic.model.Owner;
import org.springframework.dao.DataAccessException;
import java.util.Collection;
public interface FindOwnerStrategy {
Collection findOwner(String value) throws DataAccessException;
}
我们可以根据具体的找用户策略来实现不同的策略类。
下面是根据id来找的策略:
package com.iflytek.petclinic.service.strategy.impl;
import com.iflytek.petclinic.bll.ClinicBll;
import com.iflytek.petclinic.model.Owner;
import com.iflytek.petclinic.service.strategy.FindOwnerStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import java.util.Collection;
public class FindOwnerByIdStrategy implements FindOwnerStrategy {
@Autowired
private ClinicBll clinicBll;
public Collection findOwner (String value) throws DataAccessException{
return clinicBll.findOwnerById(value);
}
}
下面是根据lastName来找的策略:
package com.iflytek.petclinic.service.strategy.impl;
import com.iflytek.petclinic.bll.ClinicBll;
import com.iflytek.petclinic.model.Owner;
import com.iflytek.petclinic.service.strategy.FindOwnerStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import java.util.Collection;
public class FindOwnerByLastNameStrategy implements FindOwnerStrategy {
@Autowired
private ClinicBll clinicBll;
public Collection findOwner(String value) throws DataAccessException{
return clinicBll.findOwnerByLastName(value);
}
}
这样,我们在原来TODO的地方可以这样处理
@RestController
public class OwnerService {
@Resource(name = "findOwnerStrategyMap")
private Map findOwnerStrategyMap ;
@ServiceMethod(value = "petclinic.owner.get", version = "1.0")
public Collection getOwner (@RequestParam String key,@RequestParam String value){
FindOwnerStrategy findOwnerStrategy = findOwnerStrategyMap.get(key);
return findOwnerStrategy.findOwner(value);
}
}
这里的findOwnerStrategyMap是个hashmap,key为策略名称,这里是id,loginName等等,value则为对应策略类实例的引用。具体在xml中配置。因为本文主要说的是策略模式,这些就略过了。