我创建了一个库来解析不同类型的数据。这就是图书馆的使用方式。
$parser = DataParser::factory($text);
$data = $parser->parse();
foreach($data as $name=>$datum)
echo "name: $name\nData: ".$datum."\n";
这$data
是一个实例NamedDataCollection
。这是类定义
interface Parsable{
// @returns NamedDataCollection
function parse();
// @returns bool. True if it can parse the data.
function can_parse();
}
class AParser implements Parsable{
public function parse(){
$this->check_header();
$this->check_content();
$this->parse_content();
...
}
public function can_parse(){
$this->check_header();
$this->check_content();
...
}
}
class BParser implements Parsable{
public function parse(){
...
}
public function can_parse(){
...
}
}
class ParserRegistry{
// @param $dir path where all the parsers are stored
public function __construct($dir){
}
// @returns all the available parsers by scanning files.
public function get(){
}
}
class DataParser{
public function factory($data){
$instance = null;
$pr= new ParserRegistry("/some/path");
foreach($pr->get() as $pname){
$rc = new ReflectionClass($pname);
$instance = $rc->newInstance($data);
if($instance->can_parse())
return $instance;
}
throw new ParserException("No parser found", 1);
}
}
是正确的工厂方法使用吗?
困扰我的一件事是can_parse
方法。似乎创建了很多解析器实例只是为了测试它是否可以解析文本。有没有更好的方法呢?我知道我可以使用静态方法。但是大多数解析器使用方法的某些部分parse
(见AParser
定义)。如果我将其设为静态,则无法使用这些方法。
注意:示例代码代表我遵循的模式。但是类名和场景只是示例。为示例提供现成的解决方案并不能解决我的实际问题。