更好的網(wǎng)站制作濟南seo怎么優(yōu)化
責任鏈模式
請求發(fā)送者和接收者連接成一條鏈,一個對象處理完,交給下一位,沿著鏈傳遞請求,這就是責任鏈模式。
角色
- 抽象處理者(Handler)
定義了處理請求的方法 - 具體處理者(ContreteHandler)
包含下一個抽象處理者作為成員變量,不同的處理者實現(xiàn)不同的處理邏輯,處理完了就交給下一個
案例
數(shù)據(jù)檢查者
在使用前端給后端傳入的數(shù)據(jù)前,都需要做校驗,比如數(shù)據(jù)完整性校驗等等。一個一個 if-else 寫起來比較麻煩,請使用責任鏈模式優(yōu)化代碼編寫體驗。
工具類:
Mapx:
import java.util.HashMap;public class Mapx<K, V> extends HashMap<K, V> {public static Mapx init(String key, Object value) {return new Mapx().set(key,value);}public Mapx<K, V> set(K key, V value){this.put(key, value);return this;}
}
Setx:
import java.util.HashSet;public class Setx extends HashSet {public static Setx init(Object obj){return new Setx().set(obj);}public Setx set(Object obj){this.add(obj);return this;}
}
Res:REST接口返回格式生成器
import java.util.Map;public class Res {public static Map ok(String msg, int symbol, Object data) {return Mapx.init("code",200).set("symbol",symbol).set("data",data).set("type","ok");}public static Map fail(String msg, int symbol, Object data) {return Mapx.init("code",400).set("symbol",symbol).set("data",data).set("type","fail");}
}
Checker:抽象處理者
import java.util.Map;
import java.util.Set;public interface Checker {public Checker hint(String hint);public Checker symbol(int symbol);public Checker ignore(Object ign);public Map check();public Checker next(Checker nextChecker);}
CompleteChecker:完整性檢查者
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;public class CompleteChecker implements Checker{private Object suspicion;private String hint;private int symbol;private Set ign;private Checker nextChecker;public CompleteChecker(Object suspicion) {this.suspicion = suspicion;}@Overridepublic Checker hint(String hint) {this.hint = hint;return this;}@Overridepublic Checker symbol(int symbol) {this.symbol = symbol;return this;}@Overridepublic Map check() {String result = this.is_complete(suspicion, ign);if (result!=null){Map data = Mapx.init("field", result);return Res.fail(hint, symbol, data);}if (nextChecker!=null){return nextChecker.check();}return null;}@Overridepublic Checker next(Checker nextChecker) {this.nextChecker = nextChecker;return nextChecker;}public CompleteChecker ignore(Object ign){Set ignx = (Set) ign;this.ign = ignx;return this;}private String is_complete(Object obj, Set<String> ign){if(obj==null){return "Self";}if(ign==null){ign = new HashSet<>();}Field[] fields = obj.getClass().getDeclaredFields();Boolean rs = true;for (Field field : fields) {field.setAccessible(true);Object fieldValue = null;String fieldName = "";Type fieldType = null;try {fieldValue = field.get(obj); //得到屬性值fieldType = field.getGenericType();//得到屬性類型fieldName = field.getName(); // 得到屬性名
// System.out.println("屬性類型:" + fieldType.getTypeName() + ",屬性名:" + fieldName + ",屬性值:" + fieldValue);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}if(ign.contains(fieldName)){// System.out.println(fieldName+" 屬性忽略檢測");continue;}if (fieldValue == null || fieldValue.equals("")) { //只要有一個屬性值不為null 就返回false 表示對象不為null
// System.out.println("檢測的成員變量中有空值");
// System.out.println(fieldName + "為空");
// System.out.println(fieldName + ": " + fieldValue);return fieldName;}// 如果成員是列表if (fieldValue instanceof java.util.List) {if (((List<?>) fieldValue).size()==0){return fieldName;}}}return null;}
}
Main:
public class Main {public static void main(String[] args) {User user = new User("小靳", "female", 20,new User("父親","male",50,new User("爺爺", "male", 70, null)));Checker checker = new CompleteChecker(user).ignore(Setx.init("age")).hint("user不完整");checker.next(new CompleteChecker(user.father)).ignore(Setx.init("age")).hint("father不完整").next(new CompleteChecker(user.father.father)).ignore(Setx.init("age")).hint("grandfather不完整");System.out.println("檢測結果: " + checker.check());}
}
Output:
檢測結果: {msg=grandfather不完整, symbol=0, code=400, data={field=father}, type=fail}
當然,我這個案例的代碼實現(xiàn)存在漏洞,user.father為null的時候,user.father.father是取不到的。
責任鏈模式的優(yōu)缺點
優(yōu)點:
- 使得一個對象無需知道是其他哪一個對象處理其請求,對象僅需知道該請求會被處理即可,且鏈式結構由客戶端創(chuàng)建?=>?降低了系統(tǒng)的耦合度
- 在系統(tǒng)中增加一個新的具體處理者無須修改原有系統(tǒng)源代碼,只需要在客戶端重新建立鏈式結構即可?=>?符合開閉原則
缺點:
- 由于一個請求沒有一個明確地接受者 => 無法保證它一定會被處理
- 對于較長的職責鏈 => 系統(tǒng)性能有一定影響且不利于調(diào)試
- 如果建立鏈不當,可能會造成循環(huán)調(diào)用 => 導致系統(tǒng)進入死循環(huán)
應用場景
- 有多個對象處理同一個請求且無需關心請求的處理對象時誰以及它是如何處理的 => 比如各種審批流程
- 可以動態(tài)地指定一組對象處理請求,客戶端可以動態(tài)創(chuàng)建職責鏈來處理請求,還可以改變鏈中處理者之間的先后次序 => 比如各種流程定制