java設計模式之策略模式(推薦交通工具)

UML圖:java

/**
 * @description 交通工具
 * 
 * @author shilvfei
 * 
 * @date 2018年5月10日
 */
public interface Vehicle {
	public String travel(double km);
}

 

package celve.test1.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//這是有效距離區間註解,能夠給策略添加有效區間的設置
@Target(ElementType.TYPE) // 表示只能給類添加該註解
@Retention(RetentionPolicy.RUNTIME) // 這個必需要將註解保留在運行時
@interface Km {
	
	int max() default Integer.MAX_VALUE;

	int min() default Integer.MIN_VALUE;
}
package celve.test1.annotation;

/**
 * @description  步行
 * 
 * @author shilvfei
 * 
 * @date 2018年5月10日
 */
@Km(max=1)
public class Walk implements Vehicle{

	@Override
	public String travel(double km) {
		//走路速度 1m/s
		double time = 0.0;
		if(km!=0.0){
			double m = 1000*km;
			time = m/1;
		}
		return "走路,時間:"+time;
	}

}
package celve.test1.annotation;

/**
 * @description 自行車 
 * 
 * @author shilvfei
 * 
 * @date 2018年5月10日
 */
@Km(min=1,max=3)
public class Bike implements Vehicle{

	@Override
	public String travel(double km) {
		//騎車速度 5m/s
		double time = 0.0;
		if(km!=0.0){
			double m = 1000*km;
			time = m/5;
		}
		return "騎車,時間:"+time;
	}

}
package celve.test1.annotation;

/**
 * @description 自行車 
 * 
 * @author shilvfei
 * 
 * @date 2018年5月10日
 */
@Km(min=1,max=3)
public class Bike implements Vehicle{

	@Override
	public String travel(double km) {
		//騎車速度 5m/s
		double time = 0.0;
		if(km!=0.0){
			double m = 1000*km;
			time = m/5;
		}
		return "騎車,時間:"+time;
	}

}

 

package celve.test1.annotation;

/**
 * @description
 * 
 * @author shilvfei
 * 
 * @date 2018年5月10日
 */
public class PlayContent {

	private Vehicle vehicle = new Walk();
	private double km;
	
	public  void getUtil(double km){
		this.km = km;
		VehicleFactory factory = new VehicleFactory();
		vehicle = factory.getVehicle(km);
	}
	
	public String goodProject(){
		return vehicle.travel(km);
	}
	
}
package celve.test1.annotation;

import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

/**
 * @description
 * 
 * @author shilvfei
 * 
 * @date 2018年5月10日
 */
public class VehicleFactory {

	//設置掃描包
	private String scanDemoPack = "celve.test1.annotation";
	
	//經過Java的類加載機制(ClassLoader)來動態加載某個class文件到內存當中的
	private ClassLoader classLoader = getClass().getClassLoader();
	
	//策略列表
	private List<Class<? extends Vehicle>> vehicleList;
	
	//根據路的遠近 生成相應的策略
	public Vehicle getVehicle(double km){
		 //在策略列表查找策略
		for (Class<? extends Vehicle> classz : vehicleList) {
			Km validKm = handleAnnotation(classz);
			//判斷金額是否在註解的區間
			if(validKm.min() < km && km<=validKm.max()){
				try {
					return classz.newInstance();
				} catch (Exception  e) {
					 throw new RuntimeException("策略得到失敗");
				} 
			}
		}
		throw new RuntimeException("策略得到失敗");
		
		/*if(km<=1){
			return  new Walk();
		}else if(km<=3){
			return  new Bike();
		}else{
			return  new Bus();
		}*/
	}
	
	//處理註解,咱們傳入一個策略類,返回它的註解
	private Km handleAnnotation(Class<? extends Vehicle> classz){
		Annotation[] annotations = classz.getAnnotations();
		if (annotations == null || annotations.length == 0) {
            return null;
        }
		for (int i = 0; i < annotations.length; i++) {
			if(annotations[i] instanceof Km){
				return (Km) annotations[i];
			}
		}
		return null;
	}
	
	//單例 執行init()方法
	public VehicleFactory() {
		init();
	}
	
	//在工廠初始化時要初始化策略列表
	private void init(){
		vehicleList = new ArrayList<>();
		File[] resource = getResource();//獲取全部的class文件
		Class<Vehicle> classz = null;
		try {
			classz = (Class<Vehicle>) classLoader.loadClass(Vehicle.class.getName());
		} catch (ClassNotFoundException e) {
			 throw new RuntimeException("未找到策略接口");
		}
		for (int i = 0; i < resource.length; i++) {
			 //載入包下的類
			try {
				Class<?> loadClass = classLoader.loadClass(scanDemoPack+"."+resource[i].getName().replace(".class", ""));//celve.test1.annotation.Bike 
				 //判斷是不是Vehicle的實現類而且不是Vehicle它自己,知足的話加入到策略列表
				if(Vehicle.class.isAssignableFrom(loadClass) && loadClass != classz){
					vehicleList.add((Class<? extends Vehicle>) loadClass);
				}
				
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	//獲取掃描的包下面全部的class文件
	public File[] getResource(){
		try {
			File file = new File(classLoader.getResource(scanDemoPack.replace('.', '/')).toURI());
			File[] listFiles = file.listFiles(new FileFilter() {
				@Override
				public boolean accept(File pathname) {
					if(pathname.getName().endsWith(".class")){//咱們只掃描class文件
						return true;
					}
					return false;
				}
			});
			return listFiles;
		} catch (URISyntaxException e) {
			throw new RuntimeException("未找到策略資源");
		}
	}
	
}
相關文章
相關標籤/搜索