• 重构之以委托取代继承


    参考《重构》

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

  • 相关阅读:
    js复制功能
    网页倒退监听
    CSS 设置table下tbody滚动条
    js滚动条滚动到底部 例如聊天这种
    时间格式转换器
    js插件整理和总结
    Js判断移动端是否存在客户端:如果存在则打开,如果不存在则下载
    qt布局添加控件的父控件说明
    qt控件模糊效果
    QT TCPSocket和QTCPServer使用
  • 原文地址:https://www.cnblogs.com/Robotke1/p/3264951.html
Copyright © 2020-2023  润新知