PHP中的servant模式示例?

时间:2015-01-13 10:46:42

标签: php design-patterns command-pattern

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

但不确定我是否正确行事。有什么想法吗?

1 个答案:

答案 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