摸鱼时刻 - 5分钟玩耍设计模式(1)
一、装饰器模式
假设存在一个基础
Request
类,只提供url
和method
基础属性。然而我们还想记录其他额外属性,如context
上下文。这时装饰器模式就可以派上用场了~
1. Request 类
<?php
namespace App\Request;
class Request
{
private $url;
private $method;
public function __construct($url, $method)
{
$this->url = $url;
$this->method = $method;
}
public function getUrl()
{
return $this->url;
}
public function getMethod()
{
return $this->method;
}
public function echo($msg)
{
echo "url: {$this->url}, method: {$this->method}, content: {$msg}\n";
}
}
2. MoYuRequest 类
<?php
namespace App\Request;
class MoYuRequest extends Request
{
private $request;
private $context = [];
public function __construct(Request $request)
{
$this->request = $request;
}
public function withContext($key, $value)
{
$this->context[$key] = $value;
}
public function getContext($key)
{
return $this->context[$key] ?? null;
}
public function getMethod()
{
return $this->request->getMethod();
}
public function getUrl()
{
return $this->request->getUrl();
}
public function echo($msg)
{
$context = json_encode($this->context);
echo "context: {$context}\n";
$this->request->echo($msg);
}
}
3. 看看效果
<?php
use App\Request\Request;
use App\Request\MoYuRequest;
class App
{
public function run()
{
$req = new Request("http://localhost:8080/hello", "GET");
$req->echo("hello~");
// output:
// url: http://localhost:8080/hello, method: GET, content: hello~
$req = new MoYuRequest($req);
$req->withContext("ctx", "233");
$req->echo("hello~");
// output:
// context: {"ctx":"233"}
// url: http://localhost:8080/hello, method: GET, content: hello~
}
}
二、职责链模式
现在我们想对请求内容进行验证,只有满足一定条件的请求才能触达我们真正的业务~
1. Filters 接口
<?php
namespace App\Filter;
use App\Request\MoYuRequest;
interface Filters
{
public function doFilter(MoYuRequest $request);
}
2. 简单定义几个实现
1. HeaderFilter 类
<?php
namespace App\Filter;
use App\Request\MoYuRequest;
class HeaderFilter implements Filters
{
public function doFilter(MoYuRequest $request)
{
$header = $request->getContext("header");
echo "==== header: {$header}\n";
if ($header == null) {
return false;
}
return true;
}
}
2. MethodFilter 类
<?php
namespace App\Filter;
use App\Request\MoYuRequest;
class MethodFilter implements Filters
{
public function doFilter(MoYuRequest $request)
{
$method = $request->getMethod();
echo "==== method: {$method}\n";
if ($method == null || strtoupper($method) != "POST") {
return false;
}
return true;
}
}
3. FiltersChain 类
<?php
namespace App\Filter;
use App\Request\MoYuRequest;
class FiltersChain implements Filters
{
private $filterList = [];
public function addFilter(Filters $filters)
{
array_push($this->filterList, $filters);
}
public function doFilter(MoYuRequest $request)
{
foreach ($this->filterList as $filter) {
if (!$filter->doFilter($request)) {
return false;
}
}
return true;
}
}
4. 看看效果
<?php
use App\Request\Request;
use App\Request\MoYuRequest;
use App\Filter\FiltersChain;
use App\Filter\HeaderFilter;
use App\Filter\MethodFilter;
class App
{
public function run()
{
$req = new Request("http://localhost:8080/hello", "GET");
$req = new MoYuRequest($req);
$req->withContext("header", "233");
$this->hello($req);
// output:
// ==== header: 233
// ==== method: GET
// filter error
}
public function hello(MoYuRequest $request)
{
$chain = new FiltersChain();
$chain->addFilter(new HeaderFilter());
$chain->addFilter(new MethodFilter());
if (!$chain->doFilter($request)) {
echo "filter error" . "\n";
return;
}
$request->echo("hello~");
}
}
end~
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: