开发者

observer design pattern question

开发者 https://www.devze.com 2023-04-07 17:29 出处:网络
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.

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 {
         p开发者_如何学JAVAublic 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 Position object inside update method of OrderItemPickObserver class. Instead, what I would suggest is to keep a Position object as a property of OrderItem class so that you can set it from outside.

class OrderItem extends Observable {
         private $_position;
         public function setPosition($position){
              $this->_position = $position;
         }  
         public function getPosition(){
              return $this->_position;
         }  
    }

Then update OrderItemPickObserver class:

class OrderItemPickObserver implements Observer {
         public function update($orderitem){
               $position = $orderitem->getPosition());
               $position->setQty($position->getQty() - $orderItem->getPickedQty());
               $position->save();
         }
    }

And your calling code:

$orderitem = new OrderItem(123);    
$position = new Position();
$position->addObserver(new ProductPositionObserver());
$orderitem->setPosition($position);

This way you can decouple OrderItemPickObserver and Position classes.

EDITED:

If your business logic doesn't allow you to have a Position object in OrderItem class, you can move the same to OrderItemPickObserver since this is the class which actually uses the Position object.

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();
             }
        }

And your calling code:

$orderitem = new OrderItem(123);    
$position = new Position();
$position->addObserver(new ProductPositionObserver());
...
...
$orderitem->addObserver(new OrderItemPickObserver($position)); 


I would use your second method .... its a lot clearer to read and understand than the first (dependency injection)- good examples (although an old document) are given here -> http://www.ibm.com/developerworks/library/os-php-designptrns/

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号