вопрос о шаблоне наблюдателя - PullRequest
1 голос
/ 27 сентября 2011

Я создаю oop-систему в 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');

Или же, если оба метода неверны, я очень заинтересован в вашей информации.

будет ли этот пример наиболее идеальным, если удалить зависимость между элементом порядка и позицией?

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

Ответы [ 2 ]

0 голосов
/ 27 сентября 2011

Второй пример выглядит хорошо, но я не уверен, создаю ли новый Position объект внутри метода обновления класса OrderItemPickObserver. Вместо этого я хотел бы сохранить объект 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 классы.

РЕДАКТИРОВАНИЕ:

Если ваша бизнес-логика не позволяет иметь объект Position в классе OrderItem, вы можете переместить его в 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)); 
0 голосов
/ 27 сентября 2011

Я бы использовал ваш второй метод .... его намного понятнее и понятнее, чем первый (внедрение зависимостей) - хорошие примеры (хотя и старый документ) приведены здесь -> http://www.ibm.com/developerworks/library/os-php-designptrns/

...