在責任鏈模式裏,不少對象由每個對象對其下家的引用而鏈接起來造成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪個對象最終處理這個請求,這使得系統能夠在不影響客戶端的狀況下動態地從新組織和分配責任。java
以定外賣爲例,咱們一般要吃麥當勞只須要去麥當勞的網站去訂,而網站上對應的店家能夠有多個,咱們不關心究竟是哪家最後個給咱們送過來,只須要在網站發出訂單,剩下的就交給網站處理,這個時候咱們就能夠使用責任鏈模式來實現這樣的場景。web
責任鏈模式的類圖比較簡單,就只有兩種角色,抽象處理者和具體處理者,咱們這裏加上一個管理者,來維護責任鏈。spring
訂餐接口,兩個方法,一個負責處理訂單,一個用來設置下一個處理者。ide
package composibilityChain; import java.util.Map; public interface OrderHander { boolean hander(Map<String,Integer> map); void setMDL(OrderHander orderHander); }
麥當勞店,具體的處理者網站
package composibilityChain; import java.util.Map; public class MDL implements OrderHander { private static int count = 1; private int number ; private Map<String,Integer> menu; private OrderHander nextMdl; public MDL( Map<String, Integer> menu) { super(); this.number = count++; this.menu = menu; } public OrderHander getNextMdl() { return nextMdl; } public void setNextMdl(OrderHander nextMdl) { this.nextMdl = nextMdl; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public Map<String, Integer> getMenu() { return menu; } public void setMenu(Map<String, Integer> menu) { this.menu = menu; } @Override public boolean hander(Map<String, Integer> map) { if(!outOfStock(menu, map)) { for (String name : map.keySet()) { menu.put(name, menu.get(name) -map.get(name)); } System.out.println("在店鋪"+ number +"訂餐成功"); return true; } if(nextMdl==null) { return false; } return nextMdl.hander(map); } @Override public void setMDL(OrderHander orderHander) { nextMdl = orderHander; } //判斷當前店家是否有足夠的食物 public static boolean outOfStock(Map<String, Integer> menu,Map<String, Integer> order){ if (order == null || order.size() == 0) { return false; } if (menu == null || menu.size() == 0) { return true; } for (String name : order.keySet()) { if (menu.get(name) - order.get(name) < 0) { return true; } } return false; } }
麥當勞管理者,負責維護責任鏈,並提供接口供client調用this
package composibilityChain; import java.util.Map; public class MDLManager { private static MDLManager orderManager = new MDLManager(); private MDL head; private MDL last; private MDLManager() {} public static MDLManager getMDLManager() { return orderManager; } public void registeMDLs(MDL ...mdls ) { for (MDL mdl : mdls) { registeMDL(mdl); } } public void registeMDL(MDL mdl) { if(head ==null) { head = last = mdl; }else { last.setMDL(mdl); last = mdl; } } public void handerOrder(Map<String,Integer> order) { head.hander(order); } }
調用方spa
package composibilityChain; import java.util.HashMap; import java.util.Map; public class Client { public static void main(String[] args) { Map<String,Integer> menu1 = new HashMap<String,Integer>(); menu1.put("漢堡", 2); menu1.put("雞翅", 3); menu1.put("可樂", 2); MDL mdl1 = new MDL(menu1); Map<String,Integer> menu2 = new HashMap<String,Integer>(); menu2.put("漢堡", 3); menu2.put("雞翅", 2); menu2.put("可樂", 1); MDL mdl2 = new MDL(menu2); Map<String,Integer> menu3 = new HashMap<String,Integer>(); menu3.put("漢堡", 3); menu3.put("雞翅", 5); menu3.put("可樂", 7); MDL mdl3 = new MDL(menu3); MDLManager.getMDLManager().registeMDLs(mdl1,mdl2,mdl3); Map<String,Integer> order = new HashMap<String,Integer>(); order.put("漢堡", 1); order.put("雞翅", 1); order.put("可樂", 1); MDLManager.getMDLManager().handerOrder(order); } }
以上咱們便實現一個責任鏈模式,在javaweb開發中咱們免不了會使用到filter和interceptor,其實都是責任鏈模式的應用,只不過在servlet容器中各個filter並非一個鏈式結構,而是一個list,調用時去遍歷這個list,由符合條件的filter去作處理,interceptor是spring容器負責的,具體源碼我還不太清楚,有興趣的同窗能夠看下interceptor是如何使用責任鏈模式的。code