《重构:改善既有代码的设计》 在对象之间搬移特性  之 5

《重构:改善既有代码的设计》中提到过很多重构方法,关于在对象之间搬移特性的方法有8种。本文介绍:
隐藏“委托关系”  hide delegate

  • 名称: 隐藏“委托关系”  hide delegate
  • 概要:客户通过一个委托来调用另一个对象。在服务类上建立 客户所需的所有函数,用以隐藏委托关系。
  • 动机:每个对象都应该尽量少的了解系统的其他部分

《重构:改善既有代码的设计》 在对象之间搬移特性  之 5

  • 做法:
    • 对于每一个委托关系中的函数,在服务对象端建立一个简单的委托函数
    • 调整客户,令它只调用服务对象提供的函数
    • 每次调整后,编译并测试
    • 如果将来不再有任何客户需要取用delegate(受托类),便可移除服务对象中的相关访问函数
    • 编译,测试
  • 代码演示

修改之前的代码:

///////////////////////////.h
#ifndef REFACTORMOVE_H
#define REFACTORMOVE_H

class Department;
class Person
{
public:
    QString GetName();
    QString GetOfficeAreaCode();
    void SetOfficeAreaCode(QString officeAreaCode);
    Department* GetDepartment();
    void SetDepartment(Department *pdepartment);

private:
    QString m_Name;
    QString m_OfficeAreaCode;
    TelephoneNumber m_TelephoneNumber;
    Department *m_pDepartment;
};
class Department
{
public:
    Department(Person manager);
    Person GetManager();
private:
    QString m_ChargeCode;
    Person m_Manager;
};
#endif // REFACTORMOVE_H

///////////////////////////.cpp

Department* Person::GetDepartment()
{
    return m_pDepartment;
}

void Person::SetDepartment(Department *pdepartment)
{
    m_pDepartment = pdepartment;
}

Department::Department(Person manager)
{
    m_Manager = manager;
}

Person Department::GetManager()
{
    return m_Manager;
}
///////////////////////////main.cpp
    Person person;
    Department department(person);
    Person manager = person.GetDepartment()->GetManager();

如果客户希望指导某人的经理是谁,他必须要先取得Department对象。
manager = person.GetDepartment()->GetManager();
这样的编码就是对客户揭露了Department的工作原理。如果对客户隐藏Department,可以减少耦合。
于是,在Person中建立一个简单的委托函数。
修改之后的代码:

///////////////////////////.h
#ifndef REFACTORMOVE_H
#define REFACTORMOVE_H

class Person
{
public:
Person GetManager();
};

#endif // REFACTORMOVE_H

///////////////////////////.cpp
#include "RefactorMove.h"
Person Person::GetManager()
{
    return m_pDepartment->GetManager();
}
///////////////////////////main.cpp
    Person person;
    Department department(person);
    Person manager = person.GetManager();