Допустим, у меня есть эти два интерфейса (синтаксис PHP)
interface Renderable_Item
{
}
interface Item_Renderer
{
function render(Renderable_Item $item);
}
У меня есть набор классов, которые все одинаковые, но они просто не имеют ничего важного (в Item_Renderer точка зрения) общего. Все эти классы реализуют Renderable_Item потому что все они должны быть Item_Renderer. Итак Renderable_Item Интерфейс — только мой способ сгруппировать эти классы.
Классы, которые реализуют Item_Renderer сначала нужно будет определить конкретный тип, «понизить» его, а затем вызвать методы конкретного класса, так что интерфейс здесь не имеет смысла, но, на мой взгляд, он просто «подходит»
Есть ли лучший подход?
Кстати, я делаю парсер PHP, написанный на PHP. (Я знаю, что есть некоторые парсеры PHP в PERL и других, но просто для удовольствия ..;))
Сначала я разбиваю код PHP на структурированные куски (классы, которые реализуют пустой интерфейс «Code_Chunk» (= Renderable_Item, в моем примере)). Вот, например, как выглядит класс, представляющий выражение Assignment —
class Assignment implements Expression
{
/**
* @var Variable
*/
private $variable;
/**
* @var Expression
*/
private $variableValue;
/**
* @return Expression
*/
public function getVariableValue()
{
return $this->variableValue;
}
/**
* @param Expression $variableValue
*/
public function setVariableValue($variableValue)
{
$this->variableValue = $variableValue;
}
/**
* @param Variable $variable
*/
public function setVariable(Variable $variable)
{
$this->variable = $variable;
}
/**
* @return Variable
*/
public function getVariable()
{
return $this->variable;
}
}
Выражение интерфейса — это, кстати, просто еще один пустой интерфейс, расширяющий Code_Chunk, просто для того, чтобы отличать фрагменты кода, которые имеют одно значение (= выражения), от другого.
Однако нет ничего общего между этими классами, которые я могу использовать, за исключением того, что все они являются своего рода «фрагментом кода».
После этой процедуры я хочу перерисовать все разобранное дерево кода, которое представляет собой тонны структурированных экземпляров пользовательских классов, реализующих Code_Chunk. Каждый Code_Chunk имеет свой собственный класс рендеринга (реализующий Chunk_Renderer (= Item_Renderer)), принимающий только этот определенный фрагмент. Например, это класс отображения назначений
class Assignment_Renderer implements Chunk_Renderer
{
public function render(Code_Chunk $chunk)
{
if(!($chunk instanceof Assignment)){
throw new Unexpected_Chunk_Exception($chunk);
}
/**
* @var $chunk Assignment
*/
$_ = '';
$_ .= $chunk->getVariable()->toString();
$_ .= '=';
$_ .= Chunk_Renderer_Factory::render($chunk->getVariableValue());
return $_;
}
}
Chunk_Renderer_Factory — это класс, содержащий все классы рендеринга как синглтоны и решающий, какой рендерер использовать для какого чанка.
Задача ещё не решена.
Других решений пока нет …