流程图

类图

/**
 * Filename: test.php.
 * User: George
 * Date: 2017/12/24
 * Time: 下午8:58
 */
// 请假系统
class LeaveRequesModel {
    private $user = null; //请假人
    private $beginDate = null; //请假开始时间
    private $leaveDays = 0; //请假天数
    private $result; //审核结果
    public function setUser(string $user = '') {
        $this->user = $user;
    }
    public function getUser() {
        return $this->user;
    }
    public function setBeginDate(string $begin_date = '') {
        $this->beginDate = $begin_date;
    }
    public function getBeginDate() {
        return $this->beginDate;
    }
    public function setLeaveDays(int $leave_days = 0) {
        $this->leaveDays = $leave_days;
    }
    public function getLeaveDays() {
        return $this->leaveDays;
    }
    public function setResult(string $result) {
        $this->result = $result;
    }
    public function getResult() {
        return $this->result;
    }
}
interface State {
    public function doWork(StateMachine $ctx);
}
abstract class StateMachine {
    //持有一个状态对象
    protected $state; // State
    protected $businessVO = null;
    abstract function doWork();
    public function getBusinessVO() {
        return $this->businessVO;
    }
    public function setBusinessVO($vo) {
        $this->businessVO = $vo;
    }
    public function getState() {
        return $this->state;
    }
    public function setState($state){
        $this->state = $state;
    }
}
//请假流程的状态接口
interface LeaveRequestState extends State
{
    //这里可以扩展跟自己流程相关的处理
}
//****************************************上下文环境类********************
//处理客户端请求的上下文(相当于Context角色)
class LeaveRequesContext extends StateMachine
{
    public function doWork()
    {
        $this->state->doWork($this);
    }
}
class AuditOverState implements LeaveRequestState {
    public function doWork(StateMachine $ctx) {
        $vo = $ctx->getBusinessVO();
        if( !($vo instanceof LeaveRequesModel)) {
            throw new \Exception('状态类不对');
        }
        echo $vo->getUser() . ",你的请假申请己经审核结束,结果是:" . $vo->getResult() . PHP_EOL;
    }
}
//项目经理审核的状态类
class ProjectManagerState implements LeaveRequestState {
    private $auditOverState;
    private $depState;
    public function __construct() {
        $this->auditOverState =  new AuditOverState();
        $this->depState = new DepManagerState();
    }
    public function doWork(StateMachine $ctx) {
        $vo = $ctx->getBusinessVO();
        if( !($vo instanceof LeaveRequesModel)) {
            throw new \Exception('状态类不对');
        }
        echo "项目经理审核中,请稍候..." . PHP_EOL;
        echo $vo->getUser() . ",申请从 " . $vo->getBeginDate() . "开始请假,请假 " . $vo->getLeaveDays() . " 天,请部门经理审核(1为同意,2为不同意)" . PHP_EOL;
        //读取控制台输入的数据
        $a = 1;
        $result = ($a == 1) ? "同意" : "不同意";
        $vo->setResult("项目经理审核结果:" . $result);
        //根据选择的结果和条件来设置一下步
        if ($a == 1)
        {
            if($vo->getLeaveDays() > 3)
            {
                //如果请假天数大于3天,而且项目经理同意了,就提交
                //给部门经理。
                $ctx->setState($this->depState);
                $ctx->doWork(); //继续执行下一步工作
            }
            else
            {
                //请假在3天以内的,由项目经理做主,转向审核结束状态
                $ctx->setState($this->auditOverState);
                $ctx->doWork();
            }
        }
        else
        {
            //由项目经理不同意,转向审核结束状态
            $ctx->setState($this->auditOverState);
            $ctx->doWork();
        }
    }
    public function __destruct() {
        $this->auditOverState = null;
        $this->depState = null;
    }
}
//部门经理审核的状态类
class DepManagerState implements LeaveRequestState {
    private $auditOverState;
    public function __construct() {
        $this->auditOverState =  new AuditOverState();
    }
    public function doWork(StateMachine $ctx) {
        $vo = $ctx->getBusinessVO();
        if( !($vo instanceof LeaveRequesModel)) {
            throw new \Exception('状态类不对');
        }
        echo "部门经理审核中,请稍候..." . PHP_EOL;
        echo $vo->getUser() . ",申请从 " . $vo->getBeginDate() . "开始请假,请假 " . $vo->getLeaveDays() . " 天,请部门经理审核(1为同意,2为不同意)" . PHP_EOL;
        //读取控制台输入的数据 这里写成固定的
        $a = 1;
        $result = ($a == 1) ? "同意" : "不同意";
        $vo->setResult("部门经理审核结果:" . $result);
        //由项目经理审核以后,转向审核结束状态
        $ctx->setState($this->auditOverState);
        $ctx->doWork();
    }
    public function __destruct() {
        $this->auditOverState = null;
    }
}
//创建业务对象,并设置业务数据
$lrm = new LeaveRequesModel();
$lrm->setUser("小李");
$lrm->setBeginDate("2017-12-25");
$lrm->setLeaveDays(5);
//创建上下文对象
$ctx = new LeaveRequesContext();
//为上下文对象设置业务数据对象
$ctx->setBusinessVO($lrm);
$pms = new ProjectManagerState();
$ctx->setState($pms);  //向项目经理请假
//请求上下文,让上下文开始处理工作
$ctx->doWork();
项目经理审核中,请稍候…
小李,申请从 2017-12-25开始请假,请假 5 天,请部门经理审核(1为同意,2为不同意)
部门经理审核中,请稍候…
小李,申请从 2017-12-25开始请假,请假 5 天,请部门经理审核(1为同意,2为不同意)
小李,你的请假申请己经审核结束,结果是:部门经理审核结果:同意