我有以下课程和特点:
class BasicModel {
public function update() { /* some code */ }
}
class Task extends BasicModel {
use TagTrait;
}
class User extends BasicModel {}
trait TagTrait {
public function writeTag() { /* some code */ }
}
BasicModel-Class正在扩展Task和User(以及更多)。任务可以使用TagTrait定义一个函数来为每个使用类型写入标签。用户无法使用TagTrait。目标应该是,如果我在Task上调用update(),那么也应该调用trait来完成标记工作。我知道两种可能的方法。我可以覆盖Task中的update-function来调用writeTag函数,或者我必须检查BasicModel的update(),无论扩展类是否使用TagTrait,如果是,则调用writeTag-method。第一种方式并不是很聪明,因为我要多次做同样的工作。第二种方式对我来说也不是很好,但我不知道更好的方法。有什么建议吗?
答案 0 :(得分:1)
有点难看,但可以合并,可以覆盖
class BasicModel {
private static $updateMethods = [];
public final function update() {
echo "Start update\n";
$c = get_class($this);
if ( !array_key_exists($c,self::$updateMethods) ) {
self::$updateMethods[$c] = preg_grep('/^_traitUpdate_/', get_class_methods($this));
}
foreach (self::$updateMethods[$c] as $m ) {
$this->$m();
}
}
protected function _update() { echo "Update Basic\n";}
}
class Task extends BasicModel {
use TagTrait;
}
class User extends BasicModel {
}
class OtherTaggable extends BasicModel {
use TagTrait,NoteTrait;
}
class TaskChild extends Task {
use TagTrait;
protected function _update() { echo "Update TaskChid overwriten\n";}
}
trait TagTrait {
public function writeTag() { /* some code */ }
public function _traitUpdate_TagTrait() { echo "TagTrait update\n"; }
}
trait NoteTrait {
public function writeNote() { /* some code */ }
public function _traitUpdate_NoteTrait() { echo "NoteTrait update\n"; }
}
$U = new User();
$T = new Task();
$O = new OtherTaggable();
$OC= new TaskChild();
$U->update();
echo "-\n";
$T->update();
echo "-\n";
$O->update();
echo "-\n";
$OC->update();
答案 1 :(得分:0)
您可以通过撰写:
来实现它class BasicModel {
public function update() { echo 'Update'; }
}
class Tag {
public function writeTag() { echo 'Write'; }
}
abstract class TaggingModel {
private $model;
private $tag;
public function __construct(BasicModel $model, Tag $tag) {
$this->model = $model;
$this->tag = $tag;
}
public function update() {
$this->model->update();
$this->tag->writeTag();
}
}
class User extends BasicModel {};
class Task extends TaggingModel {}
// Prints `Update`
$user = new User();
$user->update();
// Prints `Update Write`
$task = new Task(new BasicModel(), new Tag());
$task->update();
限制是BasicModel update
方法必须关联它自己的属性。
如果我们想跳过上述限制,我们可以实现组合和继承的组合:
class BasicModel {
public function update() { echo 'Update'; }
}
class Tag {
public function writeTag() { echo 'Write'; }
}
class TaggingModel extends BasicModel {
public function __construct(Tag $tag) {
$this->tag = $tag;
}
public function update() {
parent::update();
$this->tag->writeTag();
}
}
class User extends BasicModel {};
class Task extends TaggingModel {}
// Prints `Update`
$user = new User();
$user->update();
// Prints `Update Write`
$task = new Task(new Tag());
$task->update();