重构之以委托取代继承
参考《重构》
(1)原始例子:
<?php class Worker { public function inhome() { echo "inhome!!!".'<br>'; } public function eat() { echo "eat!!!".'<br>'; } public function working() { echo "working!!!".'<br>'; } public function salary() { echo "get salary!!!".'<br>'; } } class Student extends Worker { public function gotoSchool() { echo "gotoSchool!!!".'<br>'; } public function learnKnowledge() { echo "learnKnowledge!!!".'<br>'; } } $jack = new Student(); $jack->eat(); // 可以看到Student类只用到了Worker类的2个方法,这里是eat() $jack->inhome(); // 可以看到Student类只用到了Worker类的2个方法,这里是inhome() $jack->gotoSchool(); $jack->learnKnowledge(); ?>
(2)将继承关系改变为委托
<?php class Worker { public function inhome() { echo "inhome!!!".'<br>'; } public function eat() { echo "eat!!!".'<br>'; } public function working() { echo "working!!!".'<br>'; } public function getoffWork() { echo "getoffWork!!!".'<br>'; } public function salary() { echo "get salary!!!".'<br>'; } } class Student { public function inhome($worker) // Student类的方法inhome()是委托函数 { $worker->inhome(); } public function eat($worker) // Student类的方法eat()是委托函数 { $worker->eat(); } public function gotoSchool() { echo "gotoSchool!!!".'<br>'; } public function learnKnowledge() { echo "learnKnowledge!!!".'<br>'; } } $work = new Worker(); $jack = new Student(); $jack->eat($work); $jack->inhome($work); $jack->gotoSchool(); $jack->learnKnowledge(); ?>
这样子做法有些不妥之处在于需要显示的实例化两个对象,而且将其中的一个对象作为参数传给另一个对象。
(3)继续重构
<?php class Worker { public function inhome() { echo "inhome!!!".'<br>'; } public function eat() { echo "eat!!!".'<br>'; } public function working() { echo "working!!!".'<br>'; } public function getoffWork() { echo "getoffWork!!!".'<br>'; } public function salary() { echo "get salary!!!".'<br>'; } } class Student { private $worker; public function __construct() { $this->worker = new Worker(); } public function inhome() // Student类的方法inhome()是委托函数 { $this->worker->inhome(); } public function eat() // Student类的方法eat()是委托函数 { $this->worker->eat(); } public function gotoSchool() { echo "gotoSchool!!!".'<br>'; } public function learnKnowledge() { echo "learnKnowledge!!!".'<br>'; } } $jack = new Student(); $jack->eat($work); $jack->inhome($work); $jack->gotoSchool(); $jack->learnKnowledge(); ?>
这里将Worker设置为Student的一个字段,然后在Student中设置委托函数即可。
这样子做有利于封装,不用显示的将Worker对象当参数传进Student的委托函数中。