《重构:改善既有代码的设计》 重新组织数据  之 11

《重构:改善既有代码的设计》中提到过很多重构方法,关于重新组织数据的方法有16种。本文介绍:
封装集合 encapsulate collection

  • 名称:封装集合 encapsulate collection
  • 概要:有个函数返回一个集合。让这个函数返回该集合的一个只读副本,并在这个类中提供添加/移除集合元素的函数
  • 动机:对用户暴露过多对象内部数据结构的信息。不应该额外i这整个集合提供一个设值函数,应该提供为集合添加/移除元素的函数
  • 做法:
    • 加入为集合添加/移除元素的函数
    • 将保存集合的字段初始化为一个空集合
    • 编译
    • 找出集合设值函数的所有调用者。可以修改设值函数,让它使用上述“添加/移除元素”函数。也可以直接修改调用端,改让它们调用新建立的“添加/移除元素”函数
    • 编译,测试
    • 找出所有“通过取值函数获得集合斌修改其内容”的函数。逐一修改这些函数,让他们改用“添加/移除元素”函数
    • 将get集合函数的返回值修改为只读副本
    • 编译,测试
  • 代码演示

修改之前的代码: 

/.h
class Course
{
public:
    Course(QString name, bool isAdvanced);
    bool isAdvanced();
private:
    QString m_name;
    bool m_isAdvanced;
};

class student
{
public:
    QSet<Course *>& getCourseSet() ;
    void setCourseSet(QSet<Course *> pCourseSet);

private:
    QSet<Course *> m_pCourseSet;
};

//.cpp
Course::Course(QString name, bool isAdvanced)
{
    m_name = name;
    m_isAdvanced = isAdvanced;
}

bool Course::isAdvanced()
{
    return  m_isAdvanced;
}

QSet<Course *>& student::getCourseSet()
{
    return m_pCourseSet;
}

void student::setCourseSet(QSet<Course *> pCourseSet)
{
    m_pCourseSet = pCourseSet;
}
//main.cpp
 student kent;
    QSet<Course*> s;
    s.insert(new Course("Smalltalk Programming", false));
    s.insert(new Course("Appreciateing Single Malts", true));
    kent.setCourseSet(s);
    qDebug() << "course size = " << kent.getCourseSet().size();
    Course * pRefactor = new Course("Refactoring", true);
    kent.getCourseSet().insert(pRefactor);
    kent.getCourseSet().insert(new Course("Brutal Sarcasm", false));
    qDebug() << "course size = " << kent.getCourseSet().size();
    kent.getCourseSet().remove(pRefactor);
    qDebug() << "course size = " << kent.getCourseSet().size();
    int count = 0;
    for (Course* c : kent.getCourseSet())
    {
        if (c->isAdvanced() == true)
        {
            count++;
        }
    }
    qDebug() << "Advanced course count is " << count;

执行结果:

kent.getCourseSet()相关的操作,将student类内部数据暴露了。修改如下:
1) 为student中的集合建立合适的添加/删除函数
2)观察设值函数,如果有很多地点大量运用了设值函数,就需要修改设值函数,令它调用添加/移除函数。在本文中,setCourseSet()仅仅在main.cpp中使用过一次,调用之前,是个空集合。仅仅用来初始化。所以修改setCourseSet()内容为调用addCourse(),并使用rename method修改为initializeCourse().
3) 使用addCourse()和removeCourse()来增减课程
4)让getCourse()返回一个只读副本
5)main.cpp中计算高级课只使用了student的数据,所以使用extract method将这段代码提炼为一个独立函数。然后使用mobe method将其搬移到student类中。
6)将kent.getCourseSet().size() 修改为更具可读性的

修改之后的代码:

/.h
class Course
{
public:
    Course(QString name, bool isAdvanced);
    bool isAdvanced();
private:
    QString m_name;
    bool m_isAdvanced;
};

class student
{
public:
    const QSet<Course *> getCourseSet() ;
    void initializeCourse(QSet<Course *> pCourseSet);
    void addCourse(Course *pCourse);
    void removeCourse(Course *pCourse);
    int numberOfAdvancedCourses();
    int numberOfCourses();
private:
    QSet<Course *> m_pCourseSet;
};


//.cpp
Course::Course(QString name, bool isAdvanced)
{
    m_name = name;
    m_isAdvanced = isAdvanced;
}

bool Course::isAdvanced()
{
    return  m_isAdvanced;
}

const QSet<Course *> student::getCourseSet()
{
    return m_pCourseSet;
}

void student::initializeCourse(QSet<Course *> pCourseSet)
{
    for (Course *pCourse : pCourseSet)
    {
        m_pCourseSet.insert(pCourse);
    }
}

void student::addCourse(Course *pCourse)
{
    m_pCourseSet.insert(pCourse);
}

void student::removeCourse(Course *pCourse)
{
    m_pCourseSet.remove(pCourse);
}

int student::numberOfAdvancedCourses()
{
    int result = 0;
    for (Course* c : m_pCourseSet)
    {
        if (c->isAdvanced() == true)
        {
            result++;
        }
    }
    return result;
}

int student::numberOfCourses()
{
    return m_pCourseSet.size();
}
///main.cpp
student kent;
    QSet<Course*> s;
    s.insert(new Course("Smalltalk Programming", false));
    s.insert(new Course("Appreciateing Single Malts", true));
    kent.initializeCourse(s);
    qDebug() << "course size = " << kent.numberOfCourses();
    Course * pRefactor = new Course("Refactoring", true);
    kent.addCourse(pRefactor);
    kent.addCourse(new Course("Brutal Sarcasm", false));
    qDebug() << "course size = " << kent.numberOfCourses();
    kent.removeCourse(pRefactor);
    qDebug() << "course size = " << kent.numberOfCourses();
    qDebug() << "Advanced course count is " << kent.numberOfAdvancedCourses();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

giantmfc123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值