Php 抽象类-子类类型
我试图设计一些类层次结构,但我在这一部分“卡住了” 假设我有以下几节课Php 抽象类-子类类型,php,oop,abstract-class,hierarchy,children,Php,Oop,Abstract Class,Hierarchy,Children,我试图设计一些类层次结构,但我在这一部分“卡住了” 假设我有以下几节课 abstract class Video { const TYPE_MOVIE = 1; const TYPE_SHOW = 2; abstract public function getTitle(); abstract public function getType(); } class Movie extends Video { // ... public f
abstract class Video
{
const TYPE_MOVIE = 1;
const TYPE_SHOW = 2;
abstract public function getTitle();
abstract public function getType();
}
class Movie extends Video
{
// ...
public function getType()
{
return self::TYPE_MOVIE;
}
}
class Show extends Video
{
// ...
public function getType()
{
return self::TYPE_SHOW;
}
}
在系统的不同部分,我有一个(解析器)类,它封装了
电影和放映对象并返回obj。给客户
问题:获取obj类型的最佳方法是什么。从解析器/工厂类返回,以便客户端可以执行以下操作
$video = $parser->getVideo('Dumb and Dumber');
echo $video->getTitle();
// Way 1
if($video->getType == 'show') {
echo $video->getNbOfSeasons();
}
// Way 2
if($video instanceof Show) {
echo $video->getNbOfSeasons();
}
// Current way
if($video->getType == Video::TYPE_SHOW) {
echo $video->getNbOfSeasons();
}
有没有比我的解决方案更好的方法(读作:我的解决方案糟糕吗?我会选择方法2。它抽象了您需要在
Video
中添加另一个常量,以防您需要添加类SoapOpera extensed Show
(例如)
使用方式#2,您对常量的依赖性更小。无论您不需要硬编码就可以获得什么信息,这意味着如果您想要扩展,将来可能发生的问题会更少。阅读我认为第二个选项更好,使用instanceof。这是所有OOP设计的共同点,而不仅仅是PHP 在第一个选项中,您有关于基类中派生类的详细信息,因此必须为添加的每个新派生类修改基类,这应该始终避免 在添加新的派生类时保持基类不变会促进代码重用。如果有一种“正确”的方法,并且在编码过程中一切都是主观的(只要它不会对性能/可维护性产生负面影响;),那么这就是“真理”和“布雷迪”指出的第二种方法 现在这样做(抽象中的类常量)的好处是,当您与其他开发人员一起工作时,它可以提供有关您期望如何与抽象类交互的提示 例如:
$oKillerSharkFilm = Video::factory(Video::MOVIE, 'Jaws', 'Dundundundundundun');
$oKillerSharkDocumentary = Video::factory(Video::DOCUMENTARY, 'Jaws', 'A Discovery Shark Week Special');
当然,缺点是必须在抽象类中维护“允许的扩展”
您仍然可以使用问题中演示的instanceof
方法,并在摘要中维护允许扩展的列表,主要用于控件/类型修复
有没有比我的解决方案更好的方法(读作:我的解决方案糟糕吗?)
你的解决方案本身并不糟糕。然而,每当有人试图确定要执行某些操作的子类型时,我总是想知道;为什么?这个答案可能有点理论化,甚至可能有点迂腐,但这就是答案
你不应该在意。父类和子类之间的关系是子类覆盖父类的行为。A.如果您发现自己在问:如何确定子类型,您通常会做两件“错误”的事情之一:
也就是说,如果你的代码有效,并且你对它感到满意,那就去做吧。这个答案在如何处理OO方面是正确的,但我对应用程序的其他部分一无所知,所以答案是一般性的。+1个完美的例子来解释任何问题…同意-他现在这样做的唯一好处是,如果你有不被“允许”的客户端开发人员,它允许增加一个控制级别修改抽象类-在抽象中使用常量可以让其他开发人员知道如何允许他们扩展基础。我完全同意你的观点。2.正确指出了扩展和实现之间的区别。电影和甲级联赛可能会遵循一个公共界面,允许在电视上播放,但他们可能不会共享更多内容。@Berry Langerak处理这一问题的方法是,客户通过传递某个电影的名称来请求视频,在后面我搜索/获取/解析数据,然后创建并填充右obj。根据获取的数据(可以是电影、电视节目,将来可能还会有其他类型),问题是我不在乎obj的类型。我创建,但是请求obj的客户。关心。他需要知道他可以调用什么方法……所以即使电影和电视节目不共享同一个基类,客户端仍然需要检查哪个obj。(视频类型)他得到了。也许我会把整件事都写在门面课上。不管怎么说,你让我停下来,从一开始就想一想:)@MarkoJovanovic如果对象上有那么多不同的方法,那么继承是错误的工具。您只是有两个不同的实体;)