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

版权声明:请注明转发出处 https://blog.csdn.net/mafucun1988/article/details/89741613

《重构:改善既有代码的设计》中提到过很多重构方法,关于重新组织数据的方法有16种。本文介绍:
以字段取代子类 replace subclass with fields

  • 名称:以字段取代子类 replace subclass with fields
  • 概要:各个子类的唯一区别只在“返回常量数据”的函数身上。修改这些函数,使它们返回超类中的某个(新增)字段,然后销毁子类
  • 动机:子类中只有常量函数,实在没有足够的存在价值。

  • 做法:
    • 对所有子类使用replace constuctor with factory method
    • 如果有任何代码直接引用子类,令它引用超类
    • 为超类声明一个protected构造函数,用以初始化这些新增字段
    • 新建或修改子类构造函数,使它调用超类的新增构造函数
    • 编译,测试
    • 在超类中实现所有常量函数,令它们返回相应字段值,然后将该函数从子类中删掉
    • 每删掉一个常量函数,编译并测试
    • 子类中所有的常量函数都被删除后,使用inline method 将子类构造函数内联到超类的工厂函数中
    • 编译,测试
    • 将子类删掉
    • 编译,测试
  • 代码演示

修改之前的代码: 

/////////////////////////.h
class Person2
{
public:
    virtual bool isMale() = 0;
    virtual char getCode() = 0;
};

class Male : public Person2
{
public:
    bool isMale();
    char getCode();
};

class Famale : public Person2
{
public:
    bool isMale();
    char getCode();
};
//////////////////////////.cpp
bool Male::isMale()
{
    return true;
}

char Male::getCode()
{
    return 'M';
}

bool Famale::isMale()
{
    return false;
}

char Famale::getCode()
{
    return 'F';
}
/////////////////////////////main.cpp
Person2 *kent  = new Male();
qDebug() << "kent sex:" << kent->getCode();

1) 本文中,两个子类之间唯一的区别就是,它们以不同的方式实现了Person2所声明的纯虚函数getCode(),所以将这两个子类去掉。
2)使用 replace constructor with factory method,为每个子类建立一个工厂函数。
3)然后使用构造函数的地方都改为调用工厂函数
4)把两个子类都声明为private,防止其他函数使用它们
5)针对每个常量函数,在超类中声明一个对应的字段
6)针对每个常量函数,在超类中声明一个对应的字段,再为超类加上一个protected构造函数。为子类加上新构造函数,令它调用超类新增的构造函数。
7)我们可以在超类中加入访问这些字段的函数,并删除子类中的常量函数。
8)最后删除male 和 female两个子类
修改之后的代码:

/////////////////////////.h

class Person2
{
public:
    //virtual bool isMale() = 0;
//    virtual char getCode() = 0;
    char getCode();
    static Person2* createMale();
    static Person2* createFemale();
protected:
    Person2(bool isMale, char code);
private:
    bool m_isMale;
    char m_code;
};

//class Male : public Person2
//{
//public:
//    Male();
//private:
////    bool isMale();
////    char getCode();
//};

//class Female : public Person2
//{
//public:
//    Female();
//private:
////    bool isMale();
////    char getCode();
//};
//////////////////////////.cpp

//Male::Male():Person2 (true, 'M')
//{

//}

//bool Male::isMale()
//{
//    return true;
//}

//char Male::getCode()
//{
//    return 'M';
//}


//Female::Female() : Person2 (false, 'F')
//{

//}

//bool Female::isMale()
//{
//    return false;
//}

//char Female::getCode()
//{
//    return 'F';
//}

char Person2::getCode()
{
    return m_code;
}

Person2 *Person2::createMale()
{
    return new Person2(true, 'M');
}

Person2 *Person2::createFemale()
{
    return new Person2(false, 'F');
}

Person2::Person2(bool isMale, char code)
{
    m_isMale = isMale;
    m_code = code;
}
///////////////////////////////main.cpp
    Person2 *kent  = Person2::createMale();
    qDebug() << "kent sex:" << kent->getCode();

猜你喜欢

转载自blog.csdn.net/mafucun1988/article/details/89741613
今日推荐