状态/策略模式——可见性问题


State/Strategy pattern – visibility problem

我正在我的一个项目中实现状态模式,并且遇到了一个设计问题;我的问题可以抽象地描述如下:

假设我有一个StatefulObject类,它有一个state属性,其中包含CurrentState对象。

我希望CurrentState对象访问的大部分功能都封装在StatefulObject对象中。

问题是允许访问此功能迫使我在StatefulObject类中提供公共方法,否则我不会公开这些方法,而且我也觉得我不应该这样做。

我欢迎大家就如何处理这个可见性问题提出建议。

如果需要的话,实现语言是PHP。

我已经把一些示例代码,根据要求:

Class StatefulObject{
    protected $state;
    public function StatefulObject(){
        $this->state = new PrepareSate($this);
    }
    public function execute(){
        $this->state->execute();
    }
    /* I am not intrested in providing public access to these methods
    Optimaly I would have this visible only for the PrepareState*/
    public function setX(){
    };
    public function setY(){
    };  
}
Abstract class StateObject{
    protected $stateFulObjectRef;
    public function StateObject(StateFulObject $ref){
        $this->stateFulObjectRef = $ref;
    }
}
 Class PrepareState extends StateObject{
    public function execute(){
        /* This is why I need the public access for */
         $this->stateFulObjectRef->setX();
         $this->stateFulObjectRef->setY();
    }
}

我认为Java中的解决方案是让setX setY方法没有访问修饰符,这意味着它们将在包级别可见。

我不认为PHP有类似的解决方案。

编辑,关于可能的答案:

我认为到目前为止我想出的最好的解决方案是使StatefulObject和StateObject继承同一个父对象(仅仅是为了可见性)。并声明setX setY方法为受保护的。在PHP中,兄弟类可以访问彼此的受保护方法-正如这里所指出的- http://www.php.net/manual/en/language.oop5.visibility.php#93743

这个问题很笼统,但我会根据我对你问题的理解(这可能不是对问题的正确理解)来回答

我建议你创建一个接口并在你的类中实现它,然后使用该接口对象与方法交互

如果您的StateObject根本不需要访问StatefulObject,那么只需在参数中传递所需的值(策略模式)。

Class StatefulObject{
    protected $state;
    public function StatefulObject(){
        $this->state = new PrepareSate($this);
    }
    public function execute(){
        $this->state->execute($this->x, $this->y);
    }
}
Class PrepareState extends StateObject{
    public function execute($x, $y){
        // Now you have access to $x and $y. 
    }
}