zoukankan      html  css  js  c++  java
  • 『重构--改善既有代码的设计』读书笔记----Hide Delegate

    所谓委托关系,就是一个类对于另一个类来说纯粹作为接口转发,即客户通过一个委托类去调用另一个对象。直白的委托关系就是委托类直接返回出目标类给客户调用,这个关系很麻烦,因为委托关系的变动就会影响客户端的代码。隐秘的委托关系很健康,当你完全隐藏之后,你委托关系的变化只会发生在委托类的内部,从而不会去影响客户。

    封装是面向对象最关键的特征之一。他意味着系统的每个对象都应该尽可能少的了解系统的其他部分,这样带来的好处就是一旦发生了变化之后,需要了解到这一变化的对象就比较少,这也就意味着你需要改动的代码可以很少,让变化可以更加容易的进行。

    在C++中你可以光明正大的把字段声明为public,但你应该还是尽量去隐藏这种字段,公开暴露这种字段带来的麻烦可以很多,应该尽量使用protected或者private。随着你开发经验的日渐丰富,你会发现有很多别的东西也可以进行封装。

    如果客户需要通过一个服务对象(委托对象)从而得到另一个对象去调用另一个对象的函数,那么客户就必须要知道这一层委托关系,万一委托关系发生变化,客户也得相应变化。你可以在服务对象上放置一个简单的委托函数,将委托关系隐藏起来,从而去除这种依赖。这样一来,如果以后委托关系发生变化,变化也只被限制在服务对象中,不会涉及到客户。对于某些或全部客户,你可能会发现,有必要先使用Extract Class,一旦你对所有客户都隐藏了关系,就不再需要在服务对象中公开被委托对象了。

    做法:

    • 对于每一个委托关系中的函数,在服务对象中建立一个简单的委托函数。
    • 调整客户,另他只调用服务对象提供的函数。
    • 每次调整后进行编译,测试。
    • 如果将来不再有任何客户需要显示去获得受托类,那么你就可以彻底移除服务对象中的相关访问函数。
    • 编译,测试。

    例子:

    class Person
    {
        Department *department() const
        {
            return m_department;
        }
    
        void setDepartment(Department *value)
        {
            m_department = value;
        }
    
        private:
            Department *m_department;
    };
    
    class Department
    {
        public:
            Department(Person *person) :
                m_manager(person)
            {
            }
            Person *manager() const
            {
                return m_manager;
            }
        private:
            QString m_chargeCode;
            Person *m_manager;
    };

    我们可以看到有Person和Department这两个类,我们来看下客户端代码,如果我有一个Person,我想要去获取他的manager,我们就必须先调用得到他的department然后再去调用mana

    manager = john->department()->manager();

    可以看到,这种调用方式无疑暴露了客户端代码对于Department类的工作原理,我们可以得到原来是Department用来跟踪经理信息的这条逻辑。这样无疑增加了客户代码和Department之间的耦合,要消除这种耦合我们就必须Hide Delegate在Person中建立委托函数

    class Person
    {
        public:
            Person *manager()
            {
                m_department->manager();
            }
    };

    然后我们修改客户端代码,让他转而调用新函数。

    manager = john->manager();

    可以看到,经过这一次修改之后,客户端代码对Department一无所知,这样无论我Person类内部与Department之间进行何种改变,我客户端代码都是稳定的。甚至如果我们完成了对Department的所有函数的委托之后,并相应修改了Person的所有客户,我就可以移除Person中对Department的访问函数了。

    ger

  • 相关阅读:
    android4.0 及以上 版本 wifi 和 蓝牙不显示 原因
    AWK命令使用 小结
    Linux xargs命令 小结
    nginx rewrite伪静态配置参数详细说明
    简评file_get_contents与curl 效率及稳定性
    zendstudio 常用快捷键
    PHP字符串三种定义方式
    PHP连贯接口
    yii学习笔记
    PHP中str_replace函数的详解
  • 原文地址:https://www.cnblogs.com/rickyk/p/4166485.html
Copyright © 2011-2022 走看看