狀態模式例子---流程控制
阿新 • • 發佈:2017-10-28
選擇 set adding @override public style 人力 tno 判斷
提到狀態模式,讓我想到了工作流,工作流就是控制一個一個的節點狀態來實現節點的跳轉,最後來控制流程。
如果上面發起了一個請假流程,這個時候第一個節點就是部門領導審核,部門領導審核通過會繼續往下走,如果不通過那麽有兩種狀態,一種是直接駁回請求,領導說,項目最近很急,任何人都不能請假,還有一種是你寫的請假申請單不對,要退回整改重新寫。審核通過後就進入下一個節點,人力資源部門審核,當然人力資源也可以駁回請求,或者要你重新整改,人力資源審核通過之後就可以休假了,這個時候還可以選擇是否發送Email。
1、相當於State類,這裏維護一個節點名稱。
/** * 節點接口 * @author gh **/ public abstract class Node { private static String name; //當前節點名稱 //節點跳轉 public abstract void nodeHandle(FlowContext context); public String getName() { return name; } public void setName(String name) {this.name = name; } }
2、創建了一個領導節點,用來維護領導審核的流程,審核通過會交給HR審核;
public class HrNode extends Node { @Override public void nodeHandle(FlowContext context) { //先判斷流程是否結束 if(!context.isFlag()){// 根據當前流程的狀態,來控制流程的走向 if (context != null && 0 == context.getStatus()) { //只有上一級審核通過後才能輪到HR審核 // 設置當前節點的名稱 setName("HR李"); //讀取上一級的審核內容並加上自己的意見 System.out.println(context.getMessage()+getName()+"審核通過"); // 審核通過 context.setStatus(0); //HR審核通過並指向下一個節點 ,如果沒有下一個節點就把狀態設置為終結 context.setFlag(true); } }else{ System.out.println("流程已經結束"); } } }
3、這裏HR審核通過並把節點設置為完結狀態;
public class HrNode extends Node { @Override public void nodeHandle(FlowContext context) { //先判斷流程是否結束 if(!context.isFlag()){ // 根據當前流程的狀態,來控制流程的走向 if (context != null && 0 == context.getStatus()) { //只有上一級審核通過後才能輪到HR審核 // 設置當前節點的名稱 setName("HR李"); //讀取上一級的審核內容並加上自己的意見 System.out.println(context.getMessage()+getName()+"審核通過"); // 審核通過 context.setStatus(0); //HR審核通過並指向下一個節點 ,如果沒有下一個節點就把狀態設置為終結 context.setFlag(true); } }else{ System.out.println("流程已經結束"); } } }
4、這裏維護一個流程控制類,它會在HR和LEAD節點之後傳遞,並分別由他們去維護各自的節點。
public class FlowContext { private boolean flag; // 代表流程是否結束 /** * 流程狀態 0:通過 1:駁回 2.退回整改 3.已申請 * */ private int status; private String message; // 消息 private Node node; // 節點信息 public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Node getNode() { return node; } public void setNode(Node node) { this.node = node; } public static boolean start(FlowContext context) { Node node = new LeadNode(); context.setNode(node); // 設置初始節點 context.setStatus(3); // 設置狀態為申請中 context.getNode().nodeHandle(context); // 發起請求 // 最後要知道是否申請成功 //判斷當前是最後一個節點並且審核通過,而且流程結束 if("HR李".equals(node.getName())&&0==context.getStatus()&&context.isFlag()){ System.out.println("審核通過,流程結束"); return true; }else{ System.out.println("審核未通過,流程已經結束"); return false; } } public FlowContext() { super(); } }
5、最後寫一個測試類測試一下:
public static void main(String[] args) { FlowContext context=new FlowContext(); context.setMessage("本人王小二,因為十一家裏有事情,所以要多請三天假,希望公司能夠審核通過"); context.start(context); }
打印結果如下
本人王小二,因為十一家裏有事情,所以要多請三天假,希望公司能夠審核通過
本人王小二,因為十一家裏有事情,所以要多請三天假,希望公司能夠審核通過張經理審核通過;HR李審核通過
審核通過,流程結束;
上面這個例子只是很簡單的模仿了一下工作流控制狀態的跳轉。狀態模式最主要的好處就是把狀態的判斷與控制放到了其服務端的內部,使得客戶端不需要去寫很多代碼判斷,來控制自己的節點跳轉,而且這樣實現的話,我們可以把每個節點都分開來處理,當流程流轉到某個節點的時候,可以去寫自己的節點流轉方法。當然狀態模式的缺點也很多,比如類的耦合度比較高,基本上三個類要同時去寫,而且會創建很多的節點類。
狀態模式例子---流程控制