【问题标题】:Examples of servant pattern in PHP?PHP中仆人模式的例子?
【发布时间】:2015-03-11 07:13:04
【问题描述】:

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

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

【问题讨论】:

    标签: php design-patterns command-pattern


    【解决方案1】:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-19
      • 1970-01-01
      相关资源
      最近更新 更多