PHP中是否有Servant pattern个例子?它似乎不是非常流行的模式,但我发现它非常有用,它比Command pattern更简单。这是一种反模式吗?
我可以发现它是用其他语言实现的,例如this(我不知道它是什么语言,但看起来像java)。
我的例子:
// Servant.
interface Servant
{
//
}
// Servable.
interface Servable
{
//
}
// Concrete Servable.
class ConcreteServable implements Servable
{
private $position;
public function setPosition($position)
{
$this->position = $position . '<br/>';
}
public function getPosition()
{
return $this->position;
}
}
// Concrete Servant.
class ConcreteServant implements Servant
{
// Method, which will move Servable implementing class to position where.
public function moveTo(Servable $Servable, $arg)
{
// Do some other stuff to ensure it moves smoothly and nicely, this is
// the place to offer the functionality.
$Servable->setPosition($arg);
}
}
$ConcreteServable = new ConcreteServable();
$ConcreteServant = new ConcreteServant();
$ConcreteServant->moveTo($ConcreteServable, 10);
echo $ConcreteServable->getPosition(); // 10
但不确定我是否正确行事。有什么想法吗?
答案 0 :(得分:0)
Servant模式在PHP中没有像其他模式那样受到关注,但这是由于服务中经常发生这种情况。 这不是反模式
在您的示例中,接口未指定类必须实现的任何方法,该接口的原因是强制类具有您所追求的方法。
我以找到here的Servant模式为例,并将其转换为PHP供参考。
这确实显示了PHP的Servant模式的一个很好的例子,但是我不会将它用于如此简单的事情。
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;
}
}
这将允许在实现MoveServant
的任何类上使用PositionedInterface
$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