さまざまなタイプのデータを解析するためのライブラリを作成しました。これが図書館の使い方です。
$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);
}
}
適切なファクトリーメソッドの使用法ですか?
私を悩ませていることの1つは、can_parse
方法です。テキストを解析できるかどうかをテストするためだけに作成されたパーサーのインスタンスがたくさんあるようです。それを行うより良い方法はありますか?私は静的メソッドを使用できることを知っています。parse
しかし、ほとんどのパーサーはメソッドの一部を使用します(AParser
定義を参照)。静的にすると、それらのメソッドを使用できなくなります。
注: コード例は、私がフォローしているパターンを表しています。ただし、クラス名とシナリオは単なる例です。この例に既製のソリューションを提供しても、実際の問題は解決しません。