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("未找到策略資源"); } } }