package com.try2better.practice.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.try2better.practice.service.version.VersionsService;

@Controller
@RequestMapping("/version")
public class VersionController {

	@Autowired
	private VersionsService versionsService;
	
	@ResponseBody
	@RequestMapping(value="/ping")
	public String ping(String version){
		return versionsService.execute(version);
	}
}
package com.try2better.practice.service.version;

import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class VersionsService {
	
	private AbastractService headVersionService;
	
	@Autowired
	private Version1Service version1Service;
	@Autowired
	private Version2Service version2Service;
	@Autowired
	private Version3Service version3Service;
	
	public String execute(String version){
		//构造责任链
		buildNextService();
		return headVersionService.execute(version);
	}
	
	
	private void buildNextService(){
		AbastractService[] abastractServiceArray = new AbastractService[]{
				version1Service,
				version2Service,
				version3Service
		};
		if(abastractServiceArray == null || abastractServiceArray.length < 1){
			throw new RuntimeException("没有处理的service!");
		}
		if(hasNull(abastractServiceArray)){
			throw new RuntimeException("有service为null的情况!");
		}
		if(isRepetitive(abastractServiceArray)){
			throw new RuntimeException("有循环依赖的情况,有可能造成死循环!");
		}
		for (int i = abastractServiceArray.length - 2; i >= 0; i--) {
			abastractServiceArray[i].setNextAbastractService(abastractServiceArray[i + 1]);
		}
		headVersionService = abastractServiceArray[0];
	}
	
	/**
	 * 判断service有无为空的情况
	 * 
	 * @param array
	 * @return  
	 * @author zhouh-b
	 * @time 2017年9月13日
	 */
	private  boolean hasNull(T[] array){
		for (int i = 0; i < array.length; i++) {
			if(array[i] == null){
				return true;
			}
		}
		return false;
	}
	
	
	/**
	 * 判断有无重复的情况,如果有可能造成死循环
	 * 
	 * @param array
	 * @return  
	 * @author zhouh-b
	 * @time 2017年9月13日
	 */
	private  boolean isRepetitive(T[] array){
		Set set = new HashSet();
		for (int i = 0; i < array.length; i++) {
			set.add(array[i]);
		}
		return (array.length != set.size());
	}
}
package com.try2better.practice.service.version;

public abstract class AbastractService {
	
	private AbastractService nextAbastractService;

	//公用的方法
	public void commonMethods(){
		//...
	}
	
	public abstract boolean canHandle(String version);
	
	public abstract String doBusiness(String version);
	
	public String execute(String version) {
		if(canHandle(version)){
			return doBusiness(version);
		}else{
			AbastractService nextService = getNextAbastractService();
			if(nextService == null){
				throw new RuntimeException("没有匹配的service能够处理version:" + version);
			}
			return nextService.execute(version);
		}
	}

	public AbastractService getNextAbastractService() {
		return nextAbastractService;
	}

	public void setNextAbastractService(AbastractService nextAbastractService) {
		this.nextAbastractService = nextAbastractService;
	}

	
	
	
}
package com.try2better.practice.service.version;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

@Service
public class Version1Service extends AbastractService{
	
	@Override
	public boolean canHandle(String version) {
		return StringUtils.isNotBlank(version) && version.equals("1");
	}

	@Override
	public String doBusiness(String version) {
		return "version 1 service handle";
	}
	
	

}
package com.try2better.practice.service.version;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

@Service
public class Version2Service extends AbastractService{

	@Override
	public boolean canHandle(String version) {
		return StringUtils.isNotBlank(version) && version.equals("2");
	}

	@Override
	public String doBusiness(String version) {
		return "version 2 service handle";
	}

}


package com.try2better.practice.service.version;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

@Service
public class Version3Service extends AbastractService{

	@Override
	public boolean canHandle(String version) {
		return StringUtils.isNotBlank(version) && version.equals("3");
	}

	@Override
	public String doBusiness(String version) {
		return "version 3 service handle";
	}

}