我想解析几种文件格式。我想知道是否正确的OOP“冒风险”创造一个无用的对象。
class ParserFactory
{
private fn;
public function ParserFactory(fn)
{
this->fn = fn;
}
public function getParser()
{
a = new FormatAParser(this->fn);
if ( a->isValid() )
{
return( a );
}
b = new FormatBParser(this->fn);
// ... and so on...
}
}
class FormatAParser
{
/*
The object is telling us if is able to continue to work...
**CLEAN OR DIRTY DESIGN ?**
*/
public function isValid()
{
header = SomeConversionAndReadingStuff();
if ( header != "formatA" )
{
return(false)
}
return(true);
}
public function parse()
{
/*
Do the parsing, using the conversion stuff done in isValid
*/
}
}
由于
修改
我有很好的答案。因此,对象可以检查自己的有效性。无论如何,我的代码是un-OOP,因为我选择了一个解析器(格式检测)的程序方式。为了改善这一点,最好使用像这样的工厂模式(PHP代码):
class Parser
{
protected $raw;
public function setRaw($raw)
{
$this->raw = $raw;
}
}
class ParserA extends Parser
{
public function __construct()
{
echo "ParserA constructor\n";
}
public function isValid()
{
if ( $this->raw == "A" )
{
return( true );
}
return(false);
}
}
class ParserB extends Parser
{
public function __construct()
{
echo "ParserB constructor\n";
}
public function isValid()
{
if ( $this->raw == "B" )
{
return( true );
}
return(false);
}
}
class ParserFactory
{
static private $parserClasses = array();
public static function registerParser($parserClassName)
{
self::$parserClasses[] = $parserClassName;
}
public static function getParser($raw)
{
foreach( self::$parserClasses as $parserClass )
{
$parser = new $parserClass();
$parser->setRaw($raw);
if ( $parser->isValid() )
{
return( $parser );
}
}
}
}
ParserFactory::registerParser("ParserA");
ParserFactory::registerParser("ParserB");
ParserFactory::getParser("B");
答案 0 :(得分:5)
更常见的设计是
public function getParser()
{
if (FormatAParser::IsRecognizedHeader(this->fn)
{
return new FormatAParser(this->fn);
}
if (FormatBParser::IsRecognizedHeader(this->fn)
{
return new FormatBParser(this->fn);
}
}
这使用类而不是对象方法来检查标题。一个明显的变化是在列表中收集不同的解析器,而不是像这样手动循环它们。这需要能够将类(而不是对象)添加到列表中。
答案 1 :(得分:1)
我不相信有任何关于让对象理解并评估其自身有效性的事情。你总是可以将isValid方法设置为静态并传入'criteria'(在这种情况下是标题。这样你就不必在知道需要之前实例化解析器了。
答案 2 :(得分:1)
我认为这里可能没有OO-ness来自于你有多个if语句的事实,每个语句显然都在检查某种类型(在这种情况下是一种文件类型)。这与我们的观念相吻合,即应该有一个代表每种文件类型的类;这种切换通常是代码气味,设计中的某些东西不太正确。但实际上,我认为你的解决方案没问题,但是MSalters更好,因为很难知道解析器是如何工作的,因为文件本身不能为你自动生成类实例。