实现功能:
用户发布的一部电影在审核时,和审核通过后,对应的操作各不相同.
一.定义两个异常
/** * 定义一个权限拒绝异常 * Class PermissionDeniedException */class PermissionDeniedException extends \Exception{ protected $message = '权限拒绝'; protected $code = 2000; public function __construct() { parent::__construct($this->message, $this->code); }}
/** * 数据未发现异常 * Class NotFoundMovieException */class NotFoundMovieException extends \Exception{ protected $message = '数据未发现'; protected $code = 404; public function __construct() { parent::__construct($this->message, $this->code); }}
二.定义一个数据类(模拟从数据库获取数据)
/** * 电影类 * Class DbMovie */class DbMovie{ const MOVIES = [ ['id' => 1, 'uid' => 10, 'title' => '铁胆雄心', 'state' => 2] ]; /** * 模拟查找数据 * @param $id * @return bool|mixed */ public function find($id) { foreach (self::MOVIES as $movie) { if ($movie['id'] === $id) { return $movie; } } return false; }}
三.定义状态接口
/** * 状态接口 * Interface MovieStateInterface */interface MovieStateInterface{ public function show($requestUid); public function delete($requestUid); public function edit($requestUid); public function update($requestUid);}
四.定义一个虚拟电影基类
/** * Class MovieState */abstract class MovieState{ protected $movie; public function __construct($movie) { $this->movie = $movie; }}
五.定义等待审核状态的电影
/** * 等待审核中的电影 * Class ReviewMovie */class ReviewMovie extends MovieState implements MovieStateInterface{ // 允许发布者自己可以查看 public function show($requestUid) { if ($requestUid === $this->movie['uid']) { return $this->movie; } else { throw new PermissionDeniedException(); } } public function delete($requestUid) { throw new PermissionDeniedException(); } public function edit($requestUid) { throw new PermissionDeniedException(); } public function update($requestUid) { throw new PermissionDeniedException(); }}
五.定义审核通过后的电影
/** * 审核通过的电影: 允许发布者查看,删除,编辑和更新,其余人只可查看 * Class NomarlMovie */class NormalMovie extends MovieState implements MovieStateInterface{ public function show($requestUid) { return $this->movie; } public function delete($requestUid) { if ($requestUid === $this->movie['uid']) { echo '删除成功'; } else { throw new PermissionDeniedException(); } } public function edit($requestUid) { if ($requestUid === $this->movie['uid']) { echo '可以编辑'; } else { throw new PermissionDeniedException(); } } public function update($requestUid) { if ($requestUid === $this->movie['uid']) { echo '更新成功'; return true; } else { throw new PermissionDeniedException(); } }}
六.状态上下文类
class Context{ // 所有状态码对应的状态类 const MOVIE_STATES = [ 1 => ReviewMovie::class, 2 => NormalMovie::class, ]; // 状态码 private $state; // 电影 private $movie; // 状态对象 private $movieState; public function __construct($movieId, $uid) { $this->uid = $uid; $movieModel = new DbMovie(); $this->movie = $movieModel->find($movieId); if ($this->movie === false) { throw new NotFoundMovieException(); } // 状态码的修改根据保存在数据库中电影的状态来改变 $this->state = $this->movie['state']; // 切换状态码 $this->setMovieState(); } protected function setMovieState() { $currentStateClass = self::MOVIE_STATES[$this->state]; $this->movieState = new $currentStateClass($this->movie); } public function show() { return $this->movieState->show($this->uid); } public function delete() { return $this->movieState->delete($this->uid); } public function edit() { return $this->movieState->edit($this->uid); } public function update() { return $this->movieState->update($this->uid); }}
七.调用
try{ $client = new Context($movieId = 1, $uid = 10); var_dump($client->show()); var_dump($client->update());} catch (NotFoundMovieException $e) { echo $e->getMessage();} catch (PermissionDeniedException $e) { echo $e->getMessage();} catch (\Exception $e) { echo $e->getMessage();}