这是我遇到的一个设计问题。假设我有一组相关的类,有一些共同的功能和一些独特的功能;
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");
}
}
处理此问题的最佳方法是什么?在运行时检查类型似乎有点hacky。我愿意改变设计。
答案 0 :(得分:1)
由于CSV和HTML都是不同的输出格式,因此为这些格式设置专用的NumberCell是有意义的。换句话说,HTMLNumberCell
和CSVNumberCell
:
class HTMLNumberCell {
public function render(TableCell $cell) {
$cell->setContent("123.45");
$cell->setClass("number");
}
}
或使用Decorator然后你必须找到一种方法在呈现之前以某种方式实例化它。
答案 1 :(得分:1)
接口是OO中可能的最高限制级别。也就是说,你不可能有一些东西使用它不知道的方法的接口。这就是为什么它的所有方法都是公开的。对于HTMLTableCell,sedID()和setClass()基本上绑在一起。相反,你应该有一个更高的执行方法来包装对这些方法的调用(以及CSV的相应setQuoted())。
这是战略模式的一个例子。答案是答案是TableCell接口没有足够的封装。 TableCell类的方法应该对Context完全透明(调用者,在本例中为NumberCell)。