2009-10-07 6 views
0

저는 PHP5에서 몇 년 동안 일해 왔으며 사이트 개발 속도를 높이기 위해 사용하는 경량 MVC 프레임 워크를 개발했습니다. 위대한 자동화 된 formbuilder, autoSQL 모듈 등이 작동합니다.

그러나 내가 개발 한 나쁜 습관 중 하나는 $ this를 쉬운 객체 매개 변수로 사용하는 것입니다. 아직 기본 클래스 (모든 사이트 변수가 정의되어 있음)에서 확장하고 setter 메서드를 사용하여 전달 된 $ this 객체로 각 객체 인스턴스를 채우지 않고도 데이터를 실제로 캡슐화하는 방법을 알아 냈습니다. 모든 것이 작동하지만 각 객체가 전체 애플리케이션 상태를 알아야한다는 것은 어리석은 일입니다. 나는 "외부"문맥에 대한 최소한의 지식 만 필요로하는 각각의 사물을 그것이 지정된 작업으로 수행하기를 바란다.

// pseudo account 

Class account extends siteBase { 

protected $formObj; 
public $custID = 1; 
public $name; 
public $email; 
// etc... 

function __construct() { 

    $this->formObj = new FormBuild($this); // easy $this passing 

    $this->formObj->getFormData(); 

    $this->formObj->build(); 

} 
} 

// pseudo form builder class 

Class FormBuild extends siteBase { 

protected $data; 

function __construct($caller) { 

    $this->set($caller); 

} 

function set($arr) { 

    foreach($arr as $key => $val) { 

    $this->$key = $val; 

    } 

} 

function getFormData() { 

    $this->data = new FormQuery($this); // more easy $this passing 

} 

function build() { 
    foreach($this->data as $key => $val) { 
    echo $key . " " . $val . "<br>"; 
    } 
} 
} 

Class FormQuery extends siteBase { 

function __construct($caller) { 

    $this->set($caller); 

} 

function query() { 

    $sql = "SELECT email, phone FROM account WHERE custID = '$this->custID'"; 

    // query & return return result, etc. 

} 

} 

는 무엇 "프로는"상황이해야합니까 : 예를 들어

,의 내가 고객의 계정 정보를 생성하는 클래스가 있다고 가정 해 보자? 인터페이스를 약간 정리하고 싶습니다 ...

답변

2

이 문제에 대한 여러 가지 방법이 있습니다. 여기에 몇 가지

  1. 글로벌 또는 클래스가 어떤 종류의 설정 클래스에서 읽을
  2. 외부 설정/정적 데이터 (INI 스타일, XML, YAML, 데이터베이스 등) 상수
  3. registry pattern
  4. The depdency injection/inversion-of-control pattern

그들은 모두 하나의 진정한 해결책이 없습니다.

+0

레지스트리가 작동 할 수 있지만, 좋은 생각입니다.내가 제공 한 예제는 실제로 다루는 대상을 다루지 않습니다. 컨트롤러는 필요에 따라 formBuilder 객체를 호출하여 요청을 처리하는 대상 클래스 (URI의 조회)를 호출합니다.이 객체 자체는 formQuery 객체를 호출하여 DB를 가져옵니다. 저장된 양식 필드 데이터). 그런 다음 컨트롤러는 컴파일 된 컨텐트를 취하여 표시 할 뷰 객체로 전송합니다. formBuild 객체를 재구성해야하므로 최소한 객체 속성을 호출해야합니다. formBuilder 및 formQuery 객체에 대한 레지스트리 배열 매개 변수를 전달하고 $ this 통과 습관에서 벗어날 수 있습니다. -) – virtualeyes

0

클라이언트 코드의 관점을 취하십시오. 파생 클래스는 상위 클래스와 동일한 인터페이스를 갖지만 다른 구현을 가져야합니다.

파생 클래스에서 사용되지 않는 부모 클래스의 메서드와 같은 지저분한 인터페이스가 없어야하며 리팩터링을 시작할 수있는 좋은 힌트가됩니다. 가장 주목할만한 또 다른 힌트는 메서드가 동일한 인수 (을 FormBuild::__construct($caller) (siteBase::__construct()에서 파생 됨)로 비교하지 않는다는 것입니다.

siteBase에 데이터베이스가 포함되어 있지만 파생 클래스에 다른 데이터베이스가 필요하면 구성을 리팩토링합니까? 공통 클래스를 추출하고 실제로 서명을 공유하는 것을 확인하고 한 번에 몇 개씩 짝을 지어보십시오.

+0

내가하고있는 일의 빈약 한 예는 위 참조. formBuilder를 재구성하면 $ this를 객체 매개 변수로 사용하는 것을 피할 수 있습니다. 제 질문에 대한 대답은, 당신이 말하고있는 것처럼, 본질적으로, 무의미하게 주위에 걸려있는 관계없는 방법을 사용하지 않고 자신의 일을 할 수있는 디자인 수업을 만드는 것입니다. 의견에 감사드립니다. 확실히 객체 프로그래밍의 표면을 긁어 내지 만 다이빙을 좋아합니다 -) – virtualeyes

+0

레지스트리 패턴은 실제로 싱글 톤을 통해 $ this를 메소드 param으로 완전히 해결합니다. 예 : 현재 개체 인스턴스에서 액세스 레지스트리 매개 변수를 원할 때 $ this-> set (reg :: getAll()); 그리고 나서 $ this-> regkey1, $ this-> regkey2 등을 사용할 수 있습니다. 아직도 setter 방식으로 메모리를 소비하고 있지만 reg :: get ('regkeyname'); – virtualeyes

0

위의 두 응답이 모두 정확합니다.

나는 응용 프로그램 기본 클래스에서 더 이상 상속 할 필요가없는 적절한 개체에 전달하는 레지스트리 개체/속성 컨테이너를 내장하고 있습니다. 약간의 번거 로움은 $ 주변을 지나가는 것에 비유되지만 더 나은 계획을 세우고 내 물건을 알아야하는 것과 모든 것을 아는 것을 정의하도록 강요합니다.

리팩터링 조언을 통해 몇 가지 작업을 수행하는 것보다 자주 사용하는 개체를 한 번에 제거 할 수있었습니다.

아직 갈 방법은 응용 프로그램의 거의 모든 곳에서 응용 프로그램에 대해 알고 익숙해졌습니다.

관련 문제