重构之以委托取代继承

参考《重构》

(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的委托函数中。

原文地址:https://www.cnblogs.com/Robotke1/p/3264951.html