Programing

PHP의 다중 상속

lottogame 2020. 8. 23. 09:40
반응형

PHP의 다중 상속


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는 다중 상속을 지원하지 않습니다.

Coming in PHP 5.4 will be traits which attempt to provide a solution to this problem.

In the meantime, you would be best to re-think your class design. You can implement multiple interfaces if you're after an extended API to your classes.

And Chris....

PHP doesn't really support multiple inheritance, but there are some (somewhat messy) ways to implement it. Check out this URL for some examples:

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

Thought they both had useful links. Can't wait to try out traits or maybe some mixins...


The Symfony framework has a mixin plugin for this, you might want to check it out -- even just for ideas, if not to use it.

The "design pattern" answer is to abstract the shared functionality into a separate component, and compose at runtime. Think about a way to abstract out the Invitation functionality out as a class that gets associated with your Message classes in some way other than inheritance.


I'm using traits in PHP 5.4 as the way of solving this. http://php.net/manual/en/language.oop5.traits.php

This allows for classic inheritance with extends, but also gives the possible of placing common functionality and properties into a 'trait'. As the manual says:

Traits is a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies.


It sounds like the decorator pattern may be suitable, but hard to tell without more details.


This is both a question and a solution....

What about the magical _call(),_get(), __set() methods? I have not yet tested this solution but what if you make a multiInherit class. A protected variable in a child class could contain an array of classes to inherit. The constructor in the multi-interface class could create instances of each of the classes that are being inherited and link them to a private property, say _ext. The __call() method could use the method_exists() function on each of the classes in the _ext array to locate the correct method to call. __get() and __set could be used to locate internal properties, or if your an expert with references you could make the properties of the child class and the inherited classes be references to the same data. The multiple inheritance of your object would be transparent to code using those objects. Also, internal objects could access the inherited objects directly if needed as long as the _ext array is indexed by class name. I have envisioned creating this super-class and have not yet implemented it as I feel that if it works than it could lead to developing some vary bad programming habits.


I have a couple of questions to ask to clarify what you are doing:

1) Does your message object just contain a message e.g. body, recipient, schedule time? 2) What do you intend to do with your Invitation object? Does it need to be treated specially compared to an EmailMessage? 3) If so WHAT is so special about it? 4) If that is then the case, why do the message types need handling differently for an invitation? 5) What if you want to send a welcome message or an OK message? Are they new objects too?

It does sound like you are trying combine too much functionality into a set of objects that should only be concerned with holding a message contents - and not how it should be handled. To me, you see, there is no difference between an invitation or a standard message. If the invitation requires special handling, then that means application logic and not a message type.

For example: a system I built had a shared base message object that was extended into SMS, Email, and other message types. However: these were not extended further - an invitation message was simply pre-defined text to be sent via a message of type Email. A specific Invitation application would be concerned with validation and other requirements for an invite. After all, all you want to do is send message X to recipient Y which should be a discrete system in its own right.


Same problem like Java. Try using interfaces with abstract functions for solving that problem


PHP does support interfaces. This could be a good bet, depending on your use-cases.


How about an Invitation class right below the Message class?

so the hierarchy goes:

Message
--- Invitation
------ TextMessage
------ EmailMessage

And in Invitation class, add the functionality that was in InvitationTextMessage and InvitationEmailMessage.

I know that Invitation isn't really a type of Message, it's more a functionality of Message. So I'm not sure if this is good OO design or not.

참고URL : https://stackoverflow.com/questions/90982/multiple-inheritance-in-php

반응형