首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP中的servant模式示例?

PHP中的servant模式示例?
EN

Stack Overflow用户
提问于 2015-01-13 18:46:42
回答 1查看 237关注 0票数 1

在PHP中有没有Servant pattern的例子?它似乎不是一个非常流行的模式,但我发现它非常有用,而且比Command pattern更简单。它是反模式吗?

我可以发现它是用其他语言实现的,比如this (我不知道它是什么语言,但看起来像java)。

我的例子:

代码语言:javascript
复制
// 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

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

EN

回答 1

Stack Overflow用户

发布于 2020-11-17 04:18:14

在PHP中,Servant模式并不像其他模式那样引起人们的注意,但这是因为它经常出现在服务中。它不是反模式

在你的例子中,接口没有指定类必须实现的任何方法,接口的原因是强制类拥有你想要的方法。

我以一个Servant模式为例,找到了here,并将其转换为PHP以供参考。

这确实展示了PHP的Servant模式的一个很好的例子,但我不会将它用于这么简单的事情。

代码语言:javascript
复制
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

代码语言:javascript
复制
$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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27920309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档