我有一个类,更具体的一个存储库。这个存储库将保存我的验证器,以便我可以随时访问它们。目前它看起来像这样:
class ValidatorRepository {
private $validators;
public function __construct() {
$this->validators = array();
}
public function get($key) {
return $this->validators[$key];
}
public function add($key, iValidator $value) {
$this->validators[$key] = $value;
}
public static function getInstance() {
//(...)
}
}
通过这门课,我想做这样的事情:
$vr = ValidatorRepository::getInstance();
$vr->add("string", new StringValidator());
如果更好的话,我可以插入除实例化对象之外的其他内容。
..以及之后的其他地方;
$vr = ValidatorRepository::getInstance();
$vr->get("string"); // should return a *new* instance of StringValidator.
这个想法是ValidatorRepository在添加这些类之前不应该知道这些类。只要我返回当前对象,这样就可以了。
但我想要一个类的 new 对象。我可以通过在每个验证器中放置一个静态getInstance()函数,或者以某种方式使用eval,但我希望可能有另一种不那么丑陋的方式。
答案 0 :(得分:1)
我相信你应该能够做这么简单的事情:
public function add( $key, iValidator $value ) {
$this->validators[ $key ] = get_class( $value ); // this call can be moved to get() if you wish
}
public function get( $key ) {
return new $this->validators[ $key ];
}
get_class()考虑了名称空间,所以如果你使用名称空间,那么它仍然可以。
稍微灵活一点的方法可能就是:
public function add( $key, iValidator $value ) {
$this->validators[ $key ] = $value;
}
public function get( $key, $new = true ) {
if ($new) {
$class = get_class( $this->validators[ $key ] );
$class = new $class;
} else {
$class = $this->validators[ $key ];
}
return $class;
}
答案 1 :(得分:1)
你应该使用的是继承:
abstract class Validated {
public function validate(){
foreach(self::VALIDATIONS as $val) {
// ...
}
}
}
class Person extends Validated {
protected $name;
const VALIDATIONS = array(
'name' => array( 'length' => new LengthValidator(15) )
);
}
或特征:
trait Validated {
function validate(){
// ...
}
}
class Person {
use Validated;
}
将所有验证逻辑推送到单个类中会违反single responsibly principle,因为它负责验证使用它的所有类。它很快就会失控。
请注意,我已使用常量进行验证 - 您很少需要在运行时更改类的验证规则。