PHP 类 - 样板还是继承?
PHP classes - boilerplate or inherit?
免责声明:我有点菜鸟,只做了 PHP 不到一年,而 OO PHP 还不到一年。
我正在写几个 类,它们都具有一些相同的功能。这是我的样板代码:
class ClassName {
// required constructor arguments
private $arg1;
// optional arguments in an array. $options array specifies their names
// and required types. '' means any type.
private $options = array('option1'=>'type', 'option2'=>'');
private $option1 = 'default_value';
private $option2 = 'default_value';
/* getters and setters would go here if I wanted them */
// this would probably change after debugging
public function __toString() {
return print_r(get_object_vars($this), true);
}
public function __construct($arg1, array $options = array()) {
// set all required args
$this->arg1 = $arg1;
// cycle through $options array, check they are allowed,
// and check their type
foreach ($options as $option => $value) {
$type = $this->options[$option]; // no value = any type is OK
if (array_key_exists($option, $this->options)
&& (gettype($value) === $type || !$type)) {
$this->$option = $value;
}
}
}
// methods go here
}
我一直在使用这种格式:数组中的必需参数和可选参数,使用 foreach 循环分配所有可选变量,指定选项及其类型(我关心的主要区别是数组与非数组-array) 作为私有变量。
检查和分配每个可选参数的 foreach 循环没有改变。我可以复制并粘贴它来创建新的 类,但我也认为这样做可能会更好,以避免重复代码:
abstract class ParentClass {
public function __toString() {
return print_r(get_object_vars($this), true);
}
protected function setOptions($options) {
foreach ($options as $option => $value) {
$type = $this->options[$option]; // no value = any type is OK
if (array_key_exists($option, $this->options)
&& (gettype($value) === $type || !$type)) {
$this->$option = $value;
}
}
}
}
class ChildClass extends ParentClass{
private $arg1;
private $arg2;
private $options = array('option1'=>'string', 'option2'=>'array');
private $option1 = 'default_value';
private $option2 = array('foo', 'bar');
public function __construct($arg1, $arg2, $options = array()) {
$this->arg1 = $arg1;
$this->arg2 = $arg2;
parent::setOptions($options);
}
}
我还没有对继承做太多工作。这个好用吗?
谢谢!
这将很好地利用继承,始终减少重复代码的最佳做法。 DRY 将来需要更改或出现错误时,修改代码的麻烦要小得多。
编辑:顺便说一句,您也可以将所有构造逻辑放在父 class 的构造函数中,然后在子 class 中重写它并在您调用父构造函数时调用重新完成 class 特定逻辑。例如:
abstract class ParentClass {
public function __construct($options) {
foreach ($options as $option => $value) {
$type = $this->options[$option]; // no value = any type is OK
if (array_key_exists($option, $this->options)
&& (gettype($value) === $type || !$type)) {
$this->$option = $value;
}
}
}
public function __toString() {
return print_r(get_object_vars($this), true);
}
}
class ChildClass extends ParentClass{
private $arg1;
private $arg2;
private $options = array('option1'=>'string', 'option2'=>'array');
private $option1 = 'default_value';
private $option2 = array('foo', 'bar');
public function __construct($arg1, $arg2, $options = array()) {
$this->arg1 = $arg1;
$this->arg2 = $arg2;
parent::__construct($options);
}
}
免责声明:我有点菜鸟,只做了 PHP 不到一年,而 OO PHP 还不到一年。
我正在写几个 类,它们都具有一些相同的功能。这是我的样板代码:
class ClassName {
// required constructor arguments
private $arg1;
// optional arguments in an array. $options array specifies their names
// and required types. '' means any type.
private $options = array('option1'=>'type', 'option2'=>'');
private $option1 = 'default_value';
private $option2 = 'default_value';
/* getters and setters would go here if I wanted them */
// this would probably change after debugging
public function __toString() {
return print_r(get_object_vars($this), true);
}
public function __construct($arg1, array $options = array()) {
// set all required args
$this->arg1 = $arg1;
// cycle through $options array, check they are allowed,
// and check their type
foreach ($options as $option => $value) {
$type = $this->options[$option]; // no value = any type is OK
if (array_key_exists($option, $this->options)
&& (gettype($value) === $type || !$type)) {
$this->$option = $value;
}
}
}
// methods go here
}
我一直在使用这种格式:数组中的必需参数和可选参数,使用 foreach 循环分配所有可选变量,指定选项及其类型(我关心的主要区别是数组与非数组-array) 作为私有变量。
检查和分配每个可选参数的 foreach 循环没有改变。我可以复制并粘贴它来创建新的 类,但我也认为这样做可能会更好,以避免重复代码:
abstract class ParentClass {
public function __toString() {
return print_r(get_object_vars($this), true);
}
protected function setOptions($options) {
foreach ($options as $option => $value) {
$type = $this->options[$option]; // no value = any type is OK
if (array_key_exists($option, $this->options)
&& (gettype($value) === $type || !$type)) {
$this->$option = $value;
}
}
}
}
class ChildClass extends ParentClass{
private $arg1;
private $arg2;
private $options = array('option1'=>'string', 'option2'=>'array');
private $option1 = 'default_value';
private $option2 = array('foo', 'bar');
public function __construct($arg1, $arg2, $options = array()) {
$this->arg1 = $arg1;
$this->arg2 = $arg2;
parent::setOptions($options);
}
}
我还没有对继承做太多工作。这个好用吗?
谢谢!
这将很好地利用继承,始终减少重复代码的最佳做法。 DRY 将来需要更改或出现错误时,修改代码的麻烦要小得多。
编辑:顺便说一句,您也可以将所有构造逻辑放在父 class 的构造函数中,然后在子 class 中重写它并在您调用父构造函数时调用重新完成 class 特定逻辑。例如:
abstract class ParentClass {
public function __construct($options) {
foreach ($options as $option => $value) {
$type = $this->options[$option]; // no value = any type is OK
if (array_key_exists($option, $this->options)
&& (gettype($value) === $type || !$type)) {
$this->$option = $value;
}
}
}
public function __toString() {
return print_r(get_object_vars($this), true);
}
}
class ChildClass extends ParentClass{
private $arg1;
private $arg2;
private $options = array('option1'=>'string', 'option2'=>'array');
private $option1 = 'default_value';
private $option2 = array('foo', 'bar');
public function __construct($arg1, $arg2, $options = array()) {
$this->arg1 = $arg1;
$this->arg2 = $arg2;
parent::__construct($options);
}
}