2011-09-27 6 views
1

나는 PHP에서 oop 시스템을 만들고 있는데, 내가 줄이기를 원하는 클래스 사이에 강한 커플 링을 가지고 있으므로 더 많은 옵서버 패턴을 구현하고 싶습니다.옵저버 디자인 패턴 질문

제 질문은 이쪽입니다. 이 패턴을 디자인 할 때 모범 사례와 관련하여 한 클래스가 관찰자를 다른 클래스에 추가해도 괜찮습니다. 또는 관측자가 체인의 최상위 레벨에 계속 추가해야합니까?

예 : (존재하지만이 예를 들어 중요하지, 다른 방법은 클래스에 포함이라고하지만 가정한다.)

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

답변

0

두 번째 예제는 좋아 보이지만, OrderItemPickObserver 클래스의 업데이트 메소드 내에 새로운 Position 오브젝트를 생성하는 것이 확실하지 않습니다. 대신, 내가 제안 할 것이 OrderItem 클래스의 속성으로 Position 개체를 유지하여 외부에서 설정할 수 있도록하는 것입니다.

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

그리고 당신의 호출 코드 : 당신이 OrderItemPickObserverPosition 클래스를 분리 할 수 ​​

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

이 방법.

편집 : 비즈니스 로직 당신이 OrderItem 클래스의 Position 객체를 허용하지 않는 경우이 실제로 Position 개체를 사용하는 클래스이기 때문에

, 당신은 OrderItemPickObserver 동일한 이동할 수 있습니다.

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

뭔가 내가 전에 언급하지 않았지만 OrderItem에 다음과 같은 MySQL의 테이블 열 positionID을 포함하는 행 대표 : 개체가이 MySQL의 행 데이터를 잡고 구축 할 때 수량 가 사용자 을 qtypicked 편집중인 위치에 대한 참조를하고로 존재 그것의 주위에 래퍼 (유효성을 검사하고 특정 메서드를 기록) 어떻게 의존성을 제거하지만 여전히 연결된 비즈니스 로직을 유지하는 클래스 외부에서 위치를 추가할까요? – user966936

+0

ha ..또는 내가 필요한 개체를 주입 공장 클래스에 개체의 생성을 decouple 수 있습니다. – user966936

+0

또는 맞는 경우 EDIT에서 접근 방식을 사용할 수 있습니다. 덕분에 – Vikk