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

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

《重构:改善既有代码的设计》中提到过很多重构方法,关于重新组织数据的方法有16种。本文介绍:
将对象之间的关联由双向改为单向 change bidirectional association to unidirectional

  • 名称:将对象之间的关联由双向改为单向 change bidirectional association to unidirectional
  • 概要:两个类之间有双向关联,但其中一个类如今不再需要另一个类的特性。去除不必要的关联。
  • 动机:双向关联使两个类有了依赖

  • 做法:
    • 找出保存“你想去除的指针”的字段,检查它的每一个用户,判断是否可以去除该指针。不但要检查直接访问点,也要检查调用这些直接访问点的函数。考虑有无可能不通过指针取得被引用对象。如果有可能,就可以对取值函数使用substitute algorithm ,从而让客户在没有指针的情况下也可以使用该取值函数。对于使用该字段的所有函数,考虑将被引用对象作为参数传进去。
    • 如果客户使用了取值函数,先运用self encapsulate field将待删除字段自我封装起来,然后使用 substitute algorithm对付取值函数,令它不再使用该字段。然后编译,测试
    • 如果客户并没有使用取值函数,就可以直接修改待删除字段的所有被引用点:改以其他途径获得该字段所保存的对象,每次修改完,编译并测试
    • 如果已经没有任何函数使用待删除字段,移除所有对该字段的更新逻辑,然后移除该字段。
    • 编译,测试
  • 代码演示

修改之前的代码: 

/////////////////////////.h
#ifndef MAINWINDOWTEST_H
#define MAINWINDOWTEST_H

#include <QMainWindow>
#include <QSet>

class order;
class customer
{
public:
   QSet<order *> FriendOrders();
   void AddOrder(order * porder);
   double getDiscount();
   double getPriceFor(order *porder);
private:
    QSet<order *> m_pOrderSet;
};

class order
{
public:
    void setCustomer(customer *customer);
    customer* getCustomer() const;
    double getDiscountedPrice();

private:
    customer *m_pcustomer;
};

#endif // MAINWINDOWTEST_H

//////////////////////////.cpp
void order::setCustomer(customer *customer)
{
    if (m_pcustomer != nullptr)
    {
        m_pcustomer->FriendOrders().remove(this);
    }
    m_pcustomer = customer;
    if (m_pcustomer != nullptr)
    {
         m_pcustomer->FriendOrders().insert(this);
    }
}

customer* order::getCustomer() const
{
    return m_pcustomer;
}

double order::getDiscountedPrice()
{
    return 100 * (1 - m_pcustomer->getDiscount());
}

QSet<order *> customer::FriendOrders()
{
    return  m_pOrderSet;
}

void customer::AddOrder(order * porder)
{
    //希望在customer中也可以修改
    m_pOrderSet.insert(porder);
    porder->setCustomer(this);
}

double customer::getDiscount()
{
    return 0.95;
}

double customer::getPriceFor(order *porder)
{
    return porder->getDiscountedPrice();
}

现在问题来了,如果没有customer对象,就不会存在order对象,所以我想将从order到customer的连接移除掉。
1) 将order中的m_pcustomer移除掉,使用该变量的地方,直接传递参数
随软移除了双向关联,但两者之间还是有互相依赖。后续继续重构
修改之后的代码:

/////////////////////////.h
#ifndef MAINWINDOWTEST_H
#define MAINWINDOWTEST_H

#include <QMainWindow>
#include <QSet>

class order;
class customer
{
public:
   QSet<order *> FriendOrders();
   void AddOrder(order * porder);
   double getDiscount();
   double getPriceFor(order *porder);
private:
    QSet<order *> m_pOrderSet;
};

class order
{
public:
//    void setCustomer(customer *customer);
//    customer* getCustomer() const;
    double getDiscountedPrice(customer *customer);

private:
    //customer *m_pcustomer;
};
#endif // MAINWINDOWTEST_H

//////////////////////////.cpp
//void order::setCustomer(customer *customer)
//{
//    if (m_pcustomer != nullptr)
//    {
//        m_pcustomer->FriendOrders().remove(this);
//    }
//    m_pcustomer = customer;
//    if (m_pcustomer != nullptr)
//    {
//         m_pcustomer->FriendOrders().insert(this);
//    }
//}

//customer* order::getCustomer() const
//{
//    return m_pcustomer;
//}

double order::getDiscountedPrice(customer *customer)
{
    return 100 * (1 - customer->getDiscount());
}

QSet<order *> customer::FriendOrders()
{
    return  m_pOrderSet;
}

void customer::AddOrder(order * porder)
{
    //希望在customer中也可以修改
    m_pOrderSet.insert(porder);
    //porder->setCustomer(this);
}

double customer::getDiscount()
{
    return 0.95;
}

double customer::getPriceFor(order *porder)
{
    return porder->getDiscountedPrice(this);
}

猜你喜欢

转载自blog.csdn.net/mafucun1988/article/details/89631000