PHP5가 여전히 다중 상속을 지원하지 않는다는 사실을 우회 할 수있는 좋고 깨끗한 방법을 찾고 있습니다. 다음은 클래스 계층 구조입니다.
메시지
-TextMessage
——– InvitationTextMessage
-EmailMessage
——– InvitationEmailMessage
두 가지 유형의 Invitation * 수업은 공통점이 많습니다. 둘 다 상속받을 공통 부모 클래스 인 Invitation을 갖고 싶습니다. 안타깝게도 현재 조상 인 TextMessage 및 EmailMessage와 공통점이 많습니다. 여기에서 다중 상속에 대한 고전적인 욕구.
문제를 해결하기위한 가장 가벼운 접근 방식은 무엇입니까?
감사!
답변
Alex, 다중 상속이 필요한 대부분의 경우 객체 구조가 다소 올바르지 않다는 신호입니다. 당신이 설명한 상황에서 나는 당신이 단순히 너무 광범위한 계급 책임을 가지고 있음을 알았습니다. 메시지가 애플리케이션 비즈니스 모델의 일부인 경우 출력 렌더링에 신경 쓰지 않아야합니다. 대신 책임을 분할하고 텍스트 또는 html 백엔드를 사용하여 전달 된 메시지를 보내는 MessageDispatcher를 사용할 수 있습니다. 귀하의 코드를 모르지만 다음과 같이 시뮬레이션 해 보겠습니다.
$m = new Message();
$m->type = 'text/html';
$m->from = 'John Doe <jdoe@yahoo.com>';
$m->to = 'Random Hacker <rh@gmail.com>';
$m->subject = 'Invitation email';
$m->importBody('invitation.html');
$d = new MessageDispatcher();
$d->dispatch($m);
이렇게하면 Message 클래스에 몇 가지 전문화를 추가 할 수 있습니다.
$htmlIM = new InvitationHTMLMessage(); // html type, subject and body configuration in constructor
$textIM = new InvitationTextMessage(); // text type, subject and body configuration in constructor
$d = new MessageDispatcher();
$d->dispatch($htmlIM);
$d->dispatch($textIM);
MessageDispatcher는 type
전달 된 Message 객체의 속성에 따라 HTML 또는 일반 텍스트로 보낼지 여부를 결정합니다 .
// in MessageDispatcher class
public function dispatch(Message $m) {
if ($m->type == 'text/plain') {
$this->sendAsText($m);
} elseif ($m->type == 'text/html') {
$this->sendAsHTML($m);
} else {
throw new Exception("MIME type {$m->type} not supported");
}
}
요약하자면 책임은 두 클래스로 나뉩니다. 메시지 구성은 InvitationHTMLMessage / InvitationTextMessage 클래스에서 이루어지며 발송 알고리즘은 발송자에게 위임됩니다. 이를 전략 패턴이라고하며 여기에서 자세한 내용을 읽을 수 있습니다 .
답변
‘is-a’관계를 ‘has-a’관계로 바꿀 수 있습니까? 초대에는 메시지가있을 수 있지만 반드시 ‘is-a’메시지가 필요한 것은 아닙니다. 메시지 모델과 잘 어울리지 않는 Invitation fe가 확인 될 수 있습니다.
그것에 대해 더 알고 싶다면 ‘구성 vs. 상속’을 검색하십시오.
답변
이 스레드 에서 필을 인용 할 수 있다면 …
Java와 마찬가지로 PHP는 다중 상속을 지원하지 않습니다.
PHP 5.4에서 오는 것은 이 문제에 대한 해결책을 제공하려는 특성 이 될 것 입니다.
그 동안 수업 디자인을 다시 생각하는 것이 가장 좋습니다. 클래스에 대한 확장 API를 사용하는 경우 여러 인터페이스를 구현할 수 있습니다.
그리고 크리스 ….
PHP는 실제로 다중 상속을 지원하지 않지만이를 구현하는 몇 가지 (다소 지저분한) 방법이 있습니다. 다음 URL에서 몇 가지 예를 확인하세요.
http://www.jasny.net/articles/how-i-php-multiple-inheritance/
둘 다 유용한 링크가 있다고 생각했습니다. 특성이나 믹스 인을 시험 해보고 싶어서 기다릴 수 없습니다 …
답변
Symfony 프레임 워크에는이를위한 믹스 인 플러그인이 있습니다. 있습니다. 사용하지 않더라도 아이디어를 위해서라도 확인해보세요.
“디자인 패턴”에 대한 대답은 공유 기능을 별도의 구성 요소로 추상화하고 런타임에 구성하는 것입니다. 초대 기능을 상속 이외의 방식으로 Message 클래스와 연결되는 클래스로 추상화하는 방법을 생각해보십시오.
답변
이 문제를 해결하는 방법으로 PHP 5.4의 특성을 사용하고 있습니다.
http://php.net/manual/en/language.oop5.traits.php
이를 통해 확장을 통한 고전적인 상속이 가능하지만 공통 기능과 속성을 ‘특성’에 배치 할 수도 있습니다. 매뉴얼에 따르면 :
특성은 PHP와 같은 단일 상속 언어에서 코드를 재사용하기위한 메커니즘입니다. 트레이 트는 개발자가 다른 클래스 계층 구조에있는 여러 독립 클래스에서 메서드 세트를 자유롭게 재사용 할 수 있도록하여 단일 상속의 일부 제한을 줄이기위한 것입니다.
답변
데코레이터 패턴 이 적합 할 수있는 것처럼 들리지만 자세한 내용 없이는 구분하기 어렵습니다.
답변
이것은 질문이자 해결책입니다 ….
마법 _은 어떻습니까? call ()_get (), __set () 메서드? 아직이 솔루션을 테스트하지는 않았지만 multiInherit 클래스를 만들면 어떨까요? 자식 클래스의 보호 된 변수에는 상속 할 클래스 배열이 포함될 수 있습니다. 다중 인터페이스 클래스의 생성자는 상속되는 각 클래스의 인스턴스를 만들고 _ext와 같은 전용 속성에 연결할 수 있습니다. __call () 메서드는 _ext 배열의 각 클래스에서 method_exists () 함수를 사용하여 호출 할 올바른 메서드를 찾을 수 있습니다. __get () 및 __set을 사용하여 내부 속성을 찾거나 참조가있는 전문가 인 경우 자식 클래스의 속성과 상속 된 클래스를 동일한 데이터에 대한 참조로 만들 수 있습니다. 객체의 다중 상속은 해당 객체를 사용하는 코드에 투명합니다. 또한, 내부 객체는 _ext 배열이 클래스 이름으로 인덱싱되는 한 필요한 경우 상속 된 객체에 직접 액세스 할 수 있습니다. 나는이 슈퍼 클래스를 만들 계획을 세웠고, 그것이 작동한다면 여러 가지 나쁜 프로그래밍 습관을 개발할 수 있다고 생각하므로 아직 구현하지 않았습니다.