Servant 模式不像 PHP 中的其他模式那样引人注目,但这是因为它经常发生在服务中。
这不是反模式
在您的示例中,接口没有指定类必须实现的任何方法,接口的原因是强制类具有您所追求的方法。
我以找到here的Servant模式为例,将其转换为PHP供参考。
这确实展示了 PHP 的仆人模式如何使用的一个很好的例子,但我不会将它用于这么简单的事情。
class Position {
/** @var int */
public $x = 0;
/** @var int */
public $y = 0;
}
interface PositionedInterface {
public function getPosition(): Position;
public function setPosition(Position $position): void;
}
class MoveServant {
public static function moveTo(PositionedInterface $positioned, int $xMoveTo, int $yMoveTo): void
{
/** @var Position $newPosition */
$newPosition = new Position;
$newPosition->x = $xMoveTo;
$newPosition->y = $yMoveTo;
$positioned->setPosition($newPosition);
}
public static function moveBy(PositionedInterface $positioned, int $xMoveBy, int $yMoveBy): void
{
/** @var Position $startPosition */
$oldPosition = $positioned->getPosition();
/** @var Position $newPosition */
$newPosition = new Position;
$newPosition->x = $oldPosition->x + $xMoveBy;
$newPosition->y = $oldPosition->y + $yMoveBy;
$positioned->setPosition($newPosition);
}
}
class Triangle implements PositionedInterface
{
/** @var Position */
private $position;
function __construct()
{
$this->position = new Position();
}
/**
* @return Position
*/
public function getPosition(): Position
{
return $this->position;
}
/**
* @param Position $position
*/
public function setPosition(Position $position): void
{
$this->position = $position;
}
}
// Only fully typed out instead of extended to match example from link in question
class Ellipse implements PositionedInterface
{
/** @var Position */
private $position;
function __construct()
{
$this->position = new Position();
}
/**
* @return Position
*/
public function getPosition(): Position
{
return $this->position;
}
/**
* @param Position $position
*/
public function setPosition(Position $position): void
{
$this->position = $position;
}
}
// Only fully typed out instead of extended to match example from link in question
class Rectangle implements PositionedInterface
{
/** @var Position */
private $position;
function __construct()
{
$this->position = new Position();
}
/**
* @return Position
*/
public function getPosition(): Position
{
return $this->position;
}
/**
* @param Position $position
*/
public function setPosition(Position $position): void
{
$this->position = $position;
}
}
这将允许在任何实现PositionedInterface 的类上使用MoveServant
$myTriangle = new Triangle();
// $myRectangle->getPosition()->x = 0
// $myRectangle->getPosition()->y = 0
MoveServant::moveBy($myTriangle, 15, 30);
// $myTriangle->getPosition()->x = 15
// $myTriangle->getPosition()->y = 30
$myEllipse = new Ellipse();
// $myRectangle->getPosition()->x = 0
// $myRectangle->getPosition()->y = 0
MoveServant::moveBy($myEllipse, 20, 100);
// $myEllipse->getPosition()->x = 20
// $myEllipse->getPosition()->y = 100
MoveServant::moveBy($myEllipse, -18, -85);
// $myEllipse->getPosition()->x = 2
// $myEllipse->getPosition()->y = 15
$myRectangle = new Rectangle();
// $myRectangle->getPosition()->x = 0
// $myRectangle->getPosition()->y = 0
MoveServant::moveTo($myRectangle, 10, 20);
// $myRectangle->getPosition()->x = 10
// $myRectangle->getPosition()->y = 20
MoveServant::moveBy($myRectangle, 20, 10);
// $myRectangle->getPosition()->x = 30
// $myRectangle->getPosition()->y = 30