2010-12-23 3 views
0

저는 현재 PHP CMS에서 메뉴 클래스를 리팩터링하고 있으며, 현재 누군가가 메뉴를 만들려고 할 때 (메뉴의 제목을 전달함으로써 문제를 처리하는 가장 좋은 방법을 찾으려고합니다. 바닥 글, 유틸리티 메뉴 등)을 가지고 있지만 메뉴가 데이터베이스에 없습니다.메뉴를 처리 할 수없는 가장 좋은 방법은 예외입니까?

찾을 수있는 메뉴가있는 메뉴 객체를 만들려고하면 문제가 없으므로 요청한대로 객체를 반환 할 수 있습니다. 그들은 찾을 수없는 하나를 만들려고, 나는 현재 전자 메일을 보내는 원인이 예외를 던지고있어, 다음 빈 메뉴 개체를 만들고 반환합니다. 출력 메뉴에 대한 호출이 다음 오류없이 작동하지만, 그러나 아무 것도 출력하지 않습니다.

(위의 설정은 메뉴 클래스의 정적 메소드는 메뉴 객체를 생성하기 위해 호출되며, 필요한 경우 예외를 던지거나 요청 된 메뉴 객체 또는 빈 객체를 반환 할 수 있습니다.

모두 의미가 있습니다. 이것이 가장 좋은 방법일까요? 아니면 좀 더 우아한 해결책이 있습니까?

크리스

편집 :

여기에 메뉴를 만들라고 정적 함수의 :

static function makeMenu($id,$breakDepth=1){ 
    // try to create Menu 
    try { 
     $menu = new Menu($id, $breakDepth); 
    } 
    catch (no_menu_found_exception $e) { 
     // if we failed to find it, an email should have been sent, and create a blank menu so rest of site works without error 
     $menu = new Menu(""); 
    } 

    return $menu; 
} 

가 여기에 생성자입니다 :

function __construct($id,$breakDepth=1){ 
    $this->treeObject = Doctrine_Core::getTable('CmsMenuItemNew')->getTree(); 
    if ($id == "") { 
     // if ID supplied is empty, return an empty menu object 
     $this->rootNode = null; 
     $this->name = $id; 
     return; 
    } 
    if (is_numeric($id)) { 
     // check it exists? 
     $this->rootNode = $id; 
     $node = Doctrine_Core::getTable('CmsMenuItemNew')->findByDQL("menuid = '".$id."'")->getFirst(); 
     $this->name = $node->menutitle; 
     if ($this->name == "") $this->rootNode = null; 
     return; 
    } else { 
     $this->name = $id; 
     // find the menu ID for the supplied name 
     $table = Doctrine_Core::getTable('CmsMenuItemNew'); 
     $table->setOption("orderBy", "level"); 
     $this->rootNode = $table->findByDQL("menutitle = '$id'")->getFirst()->menuid; 

     // rootNode with supplied name not found, so look for a branch in the main menu 
     $this->breakDepth = $breakDepth;  
     if ($this->rootNode === null) { 
      throw new no_menu_found_exception("Menu not found: ".$id); 
     } 
    }   

} 

언급 한 바와 같이 - 그 아직 개발 중이므로 아직 완전히 완성되지 않았습니다.

+0

메일을 보내어 예외를 던지고 처리하면 이미 꽤 우아하게 들립니다. 어쩌면 코드 스 니펫을 게시 할 수 있습니까? – Oli

답변

0

빈 개체를 만드는 것은 좋은 일입니다. 이를위한 올바른 디자인 패턴을 SpecialObjects라고합니다. 코드를 완료하려면 MenuObject와 동일한 인터페이스를 갖는 MenuNotFound 객체를 반환해야합니다. 그러면이 MenuNotFound 객체가 인터페이스 진입 점에 반응하는 방식은 사용자가 결정합니다. 이렇게하면 반환되는 개체 유형을 확인하지 않고 연결을 허용합니다.

예외적으로 나는 personnaly가 진짜 문제 인 Exception을 선호합니다. 그러나 당신이 메일을 받고 싶다면 예외는 좋지 않을 것입니다, 아마도이 예외 나 메일 처리는 MenuNotFound init에서 할 수 있습니다.

+0

SpecialObjects 디자인 패턴을 Null Object 패턴이라고도합니다. –

+0

그건 내가 생각했던 것처럼 들린다. 그래서 내 정적 메서드에서 캐치 세그먼트에서 'new MenuNotFound()'를 호출하겠습니까? 그건 내가 엉망인 'if ($ id == "") {'섹션을 생성자에서 필요로하지 않는다는 것을 의미 할 것이다. 이것은 내가 더 멋진 솔루션이 있어야한다고 생각한 이유 중 일부라고 생각한다. 나는 이것이 내가 찾고있는 것이라고 생각한다. 나는 또한 이것이 예외를 던지기에 조금 약한 것처럼 보임에 동의한다 - 나는 정적 메소드에서 발견 된 것에 대한 검사를 할 수 있다고 생각한다. 따라서 발견되지 않았 음을 보여주기 위해 예외를 던질 필요가 없다. –

+0

예 Null 개체, 나는 항상 특수 개체를 생각 나게하지만 Null 개체는 내가 아는 한 동일한 패턴을 보인다. 한 가지 차이점은 null 객체가 메서드에 아무 것도 포함하지 않아서 아무것도 수행하지 않아야한다는 것입니다. – regilero

관련 문제