我正在我的一个项目中实现状态模式,并且遇到了一个设计问题;我的问题可以抽象地描述如下:
假设我有一个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.
}
}