我会让 Profile 成为一个抽象类并定义一种机制来从中获取属性,无论它是什么“类型”的配置文件。
Profile 类可能有一个获取属性的方法(已经设置,可能在构造它时),可能使用魔法方法。因此,任何扩展 Profile 的对象都已经有一种机制来根据设置的属性“格式化”自身。
我希望它有所帮助并使自己清楚。
更新:
这是我在尝试实现我认为您正在尝试实现的那种行为时提出的代码。
首先,让我们为格式化程序定义一个接口:
/**
* Formatter interface
*
* @category Formatter
* @package Formatter
* @author Saul Martinez <saul@sharkwebintelligence.com>
* @copyright 2012 Shark Web Intelligence
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @version 1.0
* @link http://www.sharkwebintelligence.com
*/
interface IFormatter
{
/**
* Object formatting.
*
* @return string
*/
public function format();
}
不过没什么特别的。现在让我们定义一种帮助器来保存字段或属性,在这种情况下,配置文件:
/**
* Profile field.
*
* @category Formatter
* @package Profile
* @subpackage Field
* @author Saul Martinez <saul@sharkwebintelligence.com>
* @copyright 2012 Shark Web Intelligence
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @version 1.0
* @link http://www.sharkwebintelligence.com
*/
class ProfileField
{
/**
* @var string $name Field name.
*/
public $name;
/**
* @var mixed $value Field value.
*/
public $value;
/**
* Factory method to create a profile field.
*
* @param string $name Field name.
* @param mixed $value Field value.
*
* @return ProfileField
*/
public static function factory($name, $value)
{
$field = new self();
$field->name = $name;
$field->value = $value;
return $field;
}
/**
* Format the profile field.
*
* @return string
*/
public function __toString()
{
return $this->name . ': ' . $this->value . PHP_EOL;
}
}
下一节课,Profile
上课,我试着让它变得有点灵活:
/**
* Profile.
*
* @category Formatter
* @package Profile
* @author Saul Martinez <saul@sharkwebintelligence.com>
* @copyright 2012 Shark Web Intelligence
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @version 1.0
* @link http://www.sharkwebintelligence.com
*/
abstract class Profile implements IFormatter
{
/**
* @var array $fields Profile fields.
*/
public $fields;
/**
* Constructor.
*
* - Set options.
*
* @param array $options Profile options.
*/
public function __construct($options)
{
if (is_array($options)) {
$this->setOptions($options);
}
}
/**
* Format implementation.
*
* @return string
*/
public function format()
{
$output = '';
foreach ($this->getFields() as $field) {
$output .= $field;
}
return $output;
}
/**
* Adds a field to the fields list.
*
* @param ProfileField $field Field to add.
*
* @return Profile Provides a fluent interface.
*/
public function addField(ProfileField $field)
{
$this->fields[] = $field;
return $this;
}
/**
* Set profile fields.
*
* @param array $fields Profile fields.
*
* @return Profile Provides a fluent interface.
*/
public function setFields(array $fields)
{
$this->fields = $fields;
return $this;
}
/**
* Get profile fields.
*
* @return array
*/
public function getFields()
{
return $this->fields;
}
/**
* Set profile options.
*
* @param array $options Profile options.
*
* @return Profile Provides a fluent interface.
*/
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $name => $value) {
$method = 'set' . ucfirst($name);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
}
Profile
最后是学生资料类,如果您想添加特定行为,它可以覆盖任何类方法:
/**
* Student profile.
*
* @category Formatter
* @package Profile
* @subpackage Student
* @author Saul Martinez <saul@sharkwebintelligence.com>
* @copyright 2012 Shark Web Intelligence
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @version 1.0
* @link http://www.sharkwebintelligence.com
*/
class StudentProfile extends Profile
{
}
现在,您只需要实例化StudentProfile
类并向其添加一些字段:
$studentProfile = new StudentProfile(
array(
'fields' => array(
ProfileField::factory('Name', 'Buddy'),
ProfileField::factory('Birth date', '1983/05/05'),
ProfileField::factory('Graduation date', '2000/01/01'),
),
)
);
echo $studentProfile->format();
希望它有所帮助,我让自己清楚。
更新:
我只是想补充一点,在用任何语言实现 OOP 时,我认为要牢记的一件非常重要的事情是YAGNI原则。
在抽象类时添加特性和行为可能感觉很“自然”,但仅仅添加它们并不是一个好主意,因为“你认为”你可能在特性中需要它们。因此,请三思是否需要添加方法或功能以及何时添加。