i am creating a oop system in php and would like to implement more observer patterns into it as i have heavy coupling between my classes that i wish to reduce.
my question is this.
in relation to best practice in design for this pattern is it ok for one class to add an observer to another class, that class is working with.
or should i keep the observer adding to the top most level of the chain?
example: (assume other methods called, but not included in the class, exist but are not important for this example.)
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');
Or alternatively if both methods are wrong i am very interested in your input.
would this example be the most ideal by removing dependency between orderitem and 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');
}
The second example looks good, but I’m not sure if creating new
Positionobject inside update method ofOrderItemPickObserverclass. Instead, what I would suggest is to keep aPositionobject as a property ofOrderItemclass so that you can set it from outside.Then update
OrderItemPickObserverclass:And your calling code:
This way you can decouple
OrderItemPickObserverandPositionclasses.EDITED:
If your business logic doesn’t allow you to have a
Positionobject inOrderItemclass, you can move the same toOrderItemPickObserversince this is the class which actually uses thePositionobject.And your calling code: