实现功能:
用户发布的一部电影在审核时,和审核通过后,对应的操作各不相同.
一.定义两个异常
/**
* 定义一个权限拒绝异常
* 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 '删除成功<br/>';
} else {
throw new PermissionDeniedException();
}
}
public function edit($requestUid)
{
if ($requestUid === $this->movie['uid']) {
echo '可以编辑<br/>';
} else {
throw new PermissionDeniedException();
}
}
public function update($requestUid)
{
if ($requestUid === $this->movie['uid']) {
echo '更新成功<br/>';
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();
}