我正在PHP中创建一个面向对象系统,并希望实现更多的观察者模式,因为我希望减少我的类之间的重耦合。
我的问题是这样的。与此模式的最佳设计实践相关的是,一个类是否可以将观察者添加到正在使用的另一个类中。或者我应该让观察者添加到链的最顶层?示例:(假设存在其他被调用但不包含在类中的方法,但对本示例不重要。)
class orderItem extends observable {
public function pick($qty, $user){
$this->setUser($user);
$position = new position($this->getPositionID());
$position->addObserver(new ProductObserver()); // is this the best option ? ?
$position->setQty($position->getQty() - $qty);
$position->save();
$this->notify(self::EVENT_PICK); // notify observers
}
}
class orderProductObserver implements observer {
public function update($orderitem){
$position = new position($orderitem->getPositionID());
$product = new product($position->getProductID());
if($product->getQty() < $product->getMinimum()) {
$alert = new minProductAlert($product);
}
}
}
class ProductObserver implements observer {
public function update($position){
$product = new product($position->getProductID());
if($product->getQty() < $product->getMinimum()) {
$alert = new minProductAlert($product);
}
}
}
$order = new orderItem(123);
$order->addObserver(new orderProductObserver()); // or is this the best option ??
$order->pick(2, 'bill');
或者如果这两种方法都是错误的,我对你的输入非常感兴趣。
如果去掉orderitem和position之间的依赖关系,这个例子是不是最理想的?
class OrderItem extends Observable {
public function pick($qty, $user){
$this->setUser($user);
$this->setPickedQty($qty);
$this->save();
$this->notify(self::EVENT_PICK); // notify observers
}
}
class OrderItemPickObserver implements Observer {
public function update($orderitem){
$position = new Position($orderitem->getPositionID());
$position->addObserver(new ProductPositionObserver());
$position->setQty($position->getQty() - $orderItem->getPickedQty());
$position->save();
}
}
class ProductPositionObserver implements Observer {
public function update($position){
$product = new product($position->getProductID());
if($product->getQty() < $product->getMinimum()) {
$alert = new minProductAlert($product);
}
}
}
$pickQty = 2;
$orderitem = new OrderItem(123);
$position = new Position($orderitem->getPositionID());
if($position->getQty() >= $pickQty)
{
$orderitem->addObserver(new OrderItemPickObserver()); // or is this the best option ??
$orderitem->pick($pickQty, 'bill');
}
第二个例子看起来不错,但我不确定是否在OrderItemPickObserver
类的更新方法中创建新的Position
对象。相反,我建议将Position
对象保留为OrderItem
类的属性,以便您可以从外部设置它。
class OrderItem extends Observable {
private $_position;
public function setPosition($position){
$this->_position = $position;
}
public function getPosition(){
return $this->_position;
}
}
然后更新OrderItemPickObserver
类:
class OrderItemPickObserver implements Observer {
public function update($orderitem){
$position = $orderitem->getPosition());
$position->setQty($position->getQty() - $orderItem->getPickedQty());
$position->save();
}
}
和你的呼叫代码:
$orderitem = new OrderItem(123);
$position = new Position();
$position->addObserver(new ProductPositionObserver());
$orderitem->setPosition($position);
这样你可以解耦OrderItemPickObserver
和Position
类。
编辑:
如果您的业务逻辑不允许您在OrderItem
类中拥有Position
对象,您可以将其移动到OrderItemPickObserver
,因为这是实际使用Position
对象的类。
class OrderItemPickObserver implements Observer {
private $_position;
function __construct($position){
$this->_position = $position;
}
public function update($orderitem){
$position = $this->_position;
$position->setId($orderitem->getPositionID());
$position->setQty($position->getQty() - $orderItem->getPickedQty());
$position->save();
}
}
和你的呼叫代码:
$orderitem = new OrderItem(123);
$position = new Position();
$position->addObserver(new ProductPositionObserver());
...
...
$orderitem->addObserver(new OrderItemPickObserver($position));
我会使用第二个方法....它比第一个(依赖注入)更容易阅读和理解-这里给出了很好的示例(尽管是旧文档)-> http://www.ibm.com/developerworks/library/os-php-designptrns/