PHP中的多重inheritance
我正在寻找一个很好的,干净的方式来解决这个事实,即PHP5仍然不支持多重inheritance。 这是类层次结构:
信息
– TextMessage
——– InvitationTextMessage
– EmailMessage
——– InvitationEmailMessage
这两种Invitation *类有很多共同点, 我很想有一个共同的父类,邀请,他们都将inheritance。 不幸的是,他们也和他们现在的祖先有很多共同点:TextMessage和EmailMessage。 这里传统的对多重inheritance的渴望。
解决问题最轻量化的方法是什么?
谢谢!
亚历克斯,大多数时候你需要多重inheritance是一个信号,你的对象结构有些不正确。 在你所概述的情况下,我看到你的课堂责任过于宽泛。 如果Message是应用程序业务模型的一部分,则不应该关心渲染输出。 相反,你可以拆分责任,并使用MessageDispatcher发送消息传递使用文本或HTML后端。 我不知道你的代码,但让我这样模拟它:
$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会根据传递的Message对象中的type
属性来决定是发送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"); } }
总而言之,责任分为两类。 消息configuration在InvitationHTMLMessage / InvitationTextMessage类中完成,发送algorithm委托给调度员。 这就是所谓的战略模式,你可以在这里阅读更多。
也许你可以用一个“有一个”的关系取代一个“是 – 一个”关系? 一个邀请可能有一个消息,但它不一定需要“是”的消息。 一个邀请fe可能被证实,与消息模型不一致。
search“组合与inheritance”,如果你需要更多的了解。
如果我可以在这个线程中引用菲尔…
PHP和Java一样,不支持多重inheritance。
在PHP 5.4中将会尝试提供解决这个问题的特性。
同时,你最好重新考虑你的class级devise。 你可以实现多个接口,如果你是在一个扩展的API之后的类。
和克里斯….
PHP并不真的支持多重inheritance,但是有一些(有点混乱)的方式来实现它。 看看这个URL的一些例子:
http://www.jasny.net/articles/how-i-php-multiple-inheritance/
以为他们都有有用的联系。 不能等待尝试特征或者一些混合…
Symfony框架有一个mixin插件 ,你可能想要检查一下 – 即使不是想用它的想法。
“devise模式”的答案是将共享function抽象为一个单独的组件,并在运行时组成。 考虑一种方法,将邀请function作为一个类以与inheritance之外的其他方式相关联的方式来抽象出来。
这既是一个问题,也是一个解决scheme。
怎么样神奇_ 调用(), _get(),__set()方法? 我还没有testing这个解决scheme,但是如果你做一个multiInherit类。 子类中的受保护variables可能包含要inheritance的类的数组。 多接口类中的构造函数可以创build每个被inheritance的类的实例,并将它们链接到一个私有属性,比如_ext。 __call()方法可以对_ext数组中的每个类使用method_exists()函数来定位要调用的正确方法。 __get()和__set可以用来定位内部属性,或者如果你的专家带有引用,你可以使子类和inheritance类的属性是对相同数据的引用。 对象的多重inheritance对于使用这些对象的代码是透明的。 此外,只要_ext数组按类名索引,内部对象可以直接访问inheritance对象。 我曾经设想过创build这个超级类,并且还没有实现它,因为我觉得如果它起作用,可能会导致一些不好的编程习惯。
我在PHP 5.4中使用特征来解决这个问题。 http://php.net/manual/en/language.oop5.traits.php
这允许扩展的经典inheritance,但也可以将常见的function和属性放置到“特质”中。 正如手册所说:
特性是单一inheritance语言(如PHP)中的代码重用机制。 特质旨在通过使开发人员能够在生活在不同类层次结构中的几个独立类中自由地重用一组方法,从而减less单一inheritance的某些限制。
这听起来像装饰模式可能是合适的,但很难说没有更多的细节。
我有几个问题要求澄清你在做什么:
1)你的消息对象是否包含一个消息,例如body,recipient,schedule time? 2)你打算如何处理你的邀请对象? 与EmailMessage相比,是否需要特别对待? 3)如果是这样的话有什么特别之处? 4)如果是这样的话,为什么消息types需要以不同的方式处理邀请? 5)如果您想发送欢迎消息或确定消息,该怎么办? 他们也是新的东西吗?
这听起来像是你试图将太多的function组合在一组对象中,而这些对象只应该关心持有消息的内容 – 而不是应该如何处理。 对我来说,你看,邀请或标准信息没有区别。 如果邀请需要特殊处理,那么这意味着应用程序逻辑而不是消息types。
例如:我构build的系统具有扩展到SMS,Email和其他消息types的共享基本消息对象。 然而,这些并没有进一步延伸 – 邀请信息是简单的预定义文本,通过Emailtypes的消息发送。 具体的邀请申请将涉及邀请的validation和其他要求。 毕竟,你所要做的就是把消息X发送给接收者Y,它本身应该是一个独立的系统。
像Java一样的问题。 尝试使用抽象函数接口来解决这个问题
PHP支持接口。 这可能是一个很好的select,取决于你的使用情况。
在Message类下面的Invitation类怎么样?
所以层次结构如下:
信息
—邀请
—— TextMessage
—— EmailMessage
在Invitation类中,添加InvitationTextMessage和InvitationEmailMessage中的function。
我知道邀请并不是真正的消息types,它更多的是消息的function。 所以我不确定这是否是好的OOdevise。