Php 使用类的层次结构,其中子类具有一些独特的特性
这是我有时遇到的一个设计问题。假设我有一组相关的类,有一些共同的特性和一些独特的特性Php 使用类的层次结构,其中子类具有一些独特的特性,php,oop,Php,Oop,这是我有时遇到的一个设计问题。假设我有一组相关的类,有一些共同的特性和一些独特的特性 interface TableCell { public function setContent($content); } interface HTMLTableCell extends TableCell { public function setID($id); public function setClass($class); } interface CSVTableCell ex
interface TableCell {
public function setContent($content);
}
interface HTMLTableCell extends TableCell {
public function setID($id);
public function setClass($class);
}
interface CSVTableCell extends TableCell {
public function setQuoted($quoted);
}
然后我有一些类需要与集合中的任何对象交互。使用常用的方法很容易。但我希望该类也能够使用唯一的方法,当它们可用时:
class NumberCell {
public function render(TableCell $cell) {
$cell->setContent("123.45");
// if this is a HTMLTableCell
$cell->setClass("number");
}
}
最好的处理方法是什么?在运行时检查类型似乎有点麻烦。我愿意改变设计。因为CSV和HTML都是不同的输出格式,所以为这些格式设置专用的NumberCell是有意义的。换句话说,
HTMLNumberCell
和CSVNumberCell
:
class HTMLNumberCell {
public function render(TableCell $cell) {
$cell->setContent("123.45");
$cell->setClass("number");
}
}
或者使用一种方法,但是你必须在呈现之前找到一种方法来实例化它。接口是OO中可能的最高限制级别。也就是说,您不能让某些东西使用它不知道的方法的接口。这就是为什么它的所有方法都是公开的。对于HTMLTableCell,sedID()和setClass()本质上是绑定在一起的。相反,您应该有一个更高的执行方法来包装对这些方法的调用(以及CSV的相应setQuoted()
这是战略模式的一个例子。实际上,答案是TableCell接口封装得不够。TableCell类的方法对上下文(调用者,在本例中为NumberCell)应该是完全透明的。我将尝试找到更多可以接受的方法,尽管我认为我已经接受了所有回答我问题的方法。你的意思是我应该试着将setID和setQuoted之类的东西作为通用TableCell接口的一部分吗?我所遇到的问题是,其中一些仅对某个子界面(例如HTML或CSV)有意义。所以我不太愿意把通用接口和具体实现细节混在一起。不,这不是我要说的。接口应该非常稀疏。我想说的是你应该有一个方法,比如“setContent()”或者你有什么。例如,对于Html类中的实现,它将调用setID()和setClass(),对于CSV,它将调用setQuoted()。