문제

저는 PHP5가 여전히 다중 상속을 지원하지 않는다는 사실을 해결할 수 있는 훌륭하고 깔끔한 방법을 찾고 있습니다.클래스 계층 구조는 다음과 같습니다.

메시지
-- 문자 메세지
-------- 초대텍스트 메시지
-- 이메일 메시지
-------- 초대이메일메시지

두 가지 유형의 Invitation* 수업에는 공통점이 많습니다.나는 둘 다 상속할 공통 상위 클래스인 Invitation을 갖고 싶습니다.불행하게도 그들은 현재의 조상들과도 공통점이 많습니다...텍스트 메시지 및 이메일 메시지.다중 상속에 대한 고전적 욕구가 여기에 있습니다.

문제를 해결하기 위한 가장 가벼운 접근 방식은 무엇입니까?

감사해요!

도움이 되었습니까?

해결책

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

이 방법으로 메시지 클래스에 일부 전문화를 추가할 수 있습니다.

$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는 다음에 따라 HTML 또는 일반 텍스트로 보낼지 여부를 결정합니다. type 메시지 객체의 속성이 전달되었습니다.

// 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 클래스에서 이루어지며 전송 알고리즘은 Dispatcher에 위임됩니다.이것을 전략 패턴이라고 합니다. 자세한 내용을 읽어보세요. 여기.

다른 팁

어쩌면 'is-a' 관계를 'has-a' 관계로 대체할 수 있을까요?초대에는 메시지가 있을 수 있지만 반드시 메시지일 필요는 없습니다.초대장 f.e.메시지 모델과 잘 어울리지 않는 것으로 확인될 수 있습니다.

'구성 대'를 검색하세요.상속'에 대해 더 알고 싶다면.

Phil의 말을 인용할 수 있다면 이 스레드...

PHP는 Java와 마찬가지로 다중 상속을 지원하지 않습니다.

PHP 5.4에서는 특성 이 문제에 대한 해결책을 제공하려고합니다.

그동안 수업 설계를 다시 생각해 보는 것이 가장 좋습니다.클래스에 확장 된 API를 겪은 경우 여러 인터페이스를 구현할 수 있습니다.

그리고 크리스....

PHP는 실제로 여러 상속을 지원하지는 않지만이를 구현하는 몇 가지 (다소 지저분한) 방법이 있습니다.몇 가지 예는이 URL을 확인하십시오.

http://www.jasny.net/articles/how-i-php-multiple-inheritance/

둘 다 유용한 링크가 있다고 생각했습니다.특성이나 믹스인을 시험해 보고 싶습니다...

Symfony 프레임워크에는 이를 위한 믹스인 플러그인, 사용하지 않더라도 아이디어를 위해서라도 확인하고 싶을 수도 있습니다.

"디자인 패턴"에 대한 대답은 공유 기능을 별도의 구성 요소로 추상화하고 런타임에 구성하는 것입니다.상속이 아닌 다른 방식으로 메시지 클래스와 연결되는 클래스로 초대 기능을 추상화하는 방법을 생각해 보세요.

나는 이 문제를 해결하기 위해 PHP 5.4의 특성을 사용하고 있습니다.http://php.net/manual/en/언어.oop5.traits.php

이는 확장을 통한 고전적인 상속을 허용할 뿐만 아니라 공통 기능과 속성을 '특성'에 배치할 수도 있습니다.설명서에 따르면:

Traits는 PHP와 같은 단일 상속 언어에서 코드를 재사용하기 위한 메커니즘입니다.특성은 개발자가 서로 다른 클래스 계층에 있는 여러 독립 클래스에서 메서드 세트를 자유롭게 재사용할 수 있도록 하여 단일 상속의 일부 제한을 줄이기 위한 것입니다.

그것은 다음과 같은 소리가 난다 데코레이터 패턴 적합할 수 있지만 자세한 내용 없이는 말하기 어렵습니다.

이것은 질문이자 해결책입니다....

마법같은 건 어때요 _부르다(),_get(), __set() 메소드?아직 이 솔루션을 테스트하지는 않았지만 multiInherit 클래스를 만들면 어떻게 될까요?하위 클래스의 보호된 변수에는 상속할 클래스 배열이 포함될 수 있습니다.다중 인터페이스 클래스의 생성자는 상속되는 각 클래스의 인스턴스를 생성하고 이를 개인 속성(예: _ext)에 연결할 수 있습니다.__call() 메서드는 _ext 배열의 각 클래스에 대해 method_exists() 함수를 사용하여 호출할 올바른 메서드를 찾을 수 있습니다.__get() 및 __set을 사용하여 내부 속성을 찾을 수 있습니다. 또는 참조가 있는 전문가인 경우 하위 클래스와 상속된 클래스의 속성을 동일한 데이터에 대한 참조로 만들 수 있습니다.개체의 다중 상속은 해당 개체를 사용하는 코드에 투명합니다.또한 _ext 배열이 클래스 이름으로 색인화되어 있는 한 내부 개체는 필요한 경우 상속된 개체에 직접 액세스할 수 있습니다.나는 이 슈퍼 클래스를 만드는 것을 구상했지만 아직 구현하지 않았습니다. 그것이 작동한다면 다양한 나쁜 프로그래밍 습관이 생길 수 있다고 생각하기 때문입니다.

귀하가 하고 있는 일을 명확히 하기 위해 몇 가지 질문이 있습니다.

1) 귀하의 메시지가 반대합니까? 단지 메시지를 포함합니다.본체, 수신자, 일정시간?2) 초대 대상으로 무엇을 하려고 합니까?EmailMessage와 비교하여 특별히 처리해야 합니까?3) 그렇다면 무엇이 그렇게 특별합니까?4) 그렇다면 초대에 대해 메시지 유형을 다르게 처리해야 하는 이유는 무엇입니까?5) 환영 메시지나 OK 메시지를 보내고 싶다면?그것들도 새로운 물건인가요?

메시지 내용을 보관하는 데만 관심을 두고 처리 방법은 고려하지 않는 개체 집합에 너무 많은 기능을 결합하려는 것처럼 들립니다.나에게는 초대장이나 표준 메시지 사이에 차이가 없습니다.초대에 특별한 처리가 필요한 경우 이는 메시지 유형이 아닌 애플리케이션 논리를 의미합니다.

예를 들어:내가 구축한 시스템에는 SMS, 이메일 및 기타 메시지 유형으로 확장된 공유 기본 메시지 개체가 있었습니다.하지만:이는 더 이상 확장되지 않았습니다. 초대 메시지는 단순히 이메일 유형의 메시지를 통해 전송되도록 미리 정의된 텍스트였습니다.특정 초대 애플리케이션은 초대에 대한 확인 및 기타 요구 사항과 관련이 있습니다.결국, 당신이 원하는 것은 그 자체로 별개의 시스템이어야 하는 메시지 X를 수신자 Y에게 보내는 것뿐입니다.

Java와 같은 문제입니다.해당 문제를 해결하려면 추상 기능이 포함된 인터페이스를 사용해 보세요.

PHP는 인터페이스를 지원합니다.사용 사례에 따라 이는 좋은 선택이 될 수 있습니다.

Message 클래스 바로 아래에 Invitation 클래스는 어떻습니까?

따라서 계층 구조는 다음과 같습니다.

메시지
--- 초대
------ 문자 메세지
------ 이메일 메시지

그리고 Invitation 클래스에 InvitationTextMessage 및 InvitationEmailMessage에 있던 기능을 추가합니다.

나는 초대가 실제로 메시지 유형이 아니라 메시지 기능에 가깝다는 것을 알고 있습니다.그래서 이것이 좋은 OO 디자인인지 아닌지 잘 모르겠습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top