实践《重构与模式》(C++)——Creation Method + Factory + Factory Method (二)

本文介绍了如何在C++中使用Creation Method替换构造函数,以解决多构造函数带来的问题。接着讲解了用Factory封装类以隔离内部类的创建,并通过Factory Method引入多态创建,实现更灵活的对象实例化。重构示例展示了如何将创建逻辑与业务逻辑分离,以提高代码可维护性和扩展性。
摘要由CSDN通过智能技术生成

用Creation Method替换构造函数

当类中有多个构造函数,使用过程中很容易遇到不知道调用哪一个,此时用能够说明意图的返回对象实例的Creation Method替换构造函数

考虑如下的类Loan,C++要求其构造函数的名字必须与它所属的类相同。当构造函数慢慢变多,问题也会越来越明显,当希望实例化一个Loan时,程序员不得不研究需要传入什么参数,琢磨这些构造函数代码,已选择应该调用哪一个构造函数。构造函数本身无法有效和高效地表达意图。越多的构造函数不仅容易造成选择错误,还会减缓开发速度。此外,随着迭代,许多构造函数不再使用但仍留在代码中,大多数情况下没有人会去管这些死掉的构造函数。你是否与我一样嗅到了一丝代码的坏味道呢,没错,死构造函数会使类膨胀。
在这里插入图片描述

在这里,作者提出以Creation Method来解决这些问题。所谓Creation Method,就是类中的一个静态或非静态的负责实例化类的新实例的方法

Creation Method 和 Factory Method
很多人都了解或知道一点“Factory Method”,其来源于《设计模式》DP一书中的一个创建型模式。但并非所有的创建对象的方法都是工厂模式。作者所提Creation Method来指代创建类的实例的静态方法或非静态方法。即所有Factory Method都是Creation Method,但反之则不尽然。

回到上面的类Loan,其可以用来表示贷款方式,这里有三种分别为定期贷款(term loan),循环贷款(revoler),以及循环信用定期贷款(revolving credit term loan,RCTL)。

很多同学或许会跟我一样,在面对这样的情况下很容易想到通过将Loan设计为一个抽象超类,用子类标识各种贷款。所以我希望在对这一系列构造函数进行重构之前,通过以下解释先达成一些共识:

  • 区分不同贷款的知识计算资金(capital),收益(income)和期限(duration)等数值。与其为了支持定义贷款(term loan)而创建三个子类,不如通过strategy模式设置3个不同的Strategty类。
  • 不同种类贷款切换时,修改Loan实例中的几个字段要比Loan不同子类实例中切换容易的多。

有了共识后我们要对Loan类中的所有构造函数进行重构,先来看Loan类的构造函数:

class Loan {
   
public:
    Loan(double commitment, int riskRating, Date* maturity) {
   
        Loan(commitment, 0.00, riskRating, maturity, nullptr);
    }
    
    Loan(double commitment, int riskRating, Date* maturity, Date* expiry) {
   
        Loan(commitment, 0.00, riskRating, maturity, expiry);
    }
    
    Loan(double commitment, double outstanding, int riskRating, Date* maturity, Date* expiry) {
   
        Loan(nullptr, commitment, outstanding, riskRating, maturity, expiry);
    }
    
    Loan(CapitalStrategy* capitalStrategy, double commitment, int riskRating, Date* maturity, Date* expiry) {
   
        Loan(capitalStrategy, commitment, 0.00, riskRating, maturity, expiry);
    }
    
    Loan(CapitalStrategy *capitalStrategy, double commitment, double outstanding, int riskRating, Date *maturity, Date *expiry) {
   
        _commitment = commitment;
        _outstanding = outstanding;
        _riskRating = riskRating;
        _capitalStrategy.reset(capitalStrategy);
        _maturity.reset(maturity);
        _expiry.reset(expiry);
        if (!_capitalStrategy.get()) {
   
            if (!_expiry.get()) {
   
                _capitalStrategy = make_shared<CapitalStrategy>(CapitalStrategyTermLoan());
            } else if (!_maturity.get()) {
   
                _capitalStrategy = make_shared<CapitalStrategy>(CapitalStrategyRevolver());
            } else {
   
                _capitalStrategy = make_shared<CapitalStrategy>(CapitalStrategyRCTL());
            }
        }
    };
}

在动手重构之前,我还是会忍不住提醒你记住重构成功的秘籍——小步快跑,而保证跑的的方向对的手段是构建测试用例:

class CapitalCalculateTest {
   
public:
    CapitalCalculateTest() {
   
        ...
        Loan termLoan = new Loan(commitment, riskRating, maturity);
        ...
    }
};

接下来应用Creation Method替换构造函数进行重构:

  1. 提炼函数
class CapitalCalculateTest {
   
public:
    CapitalCalculateTest() {
   
        ...
        Loan termLoan = new CreateTermLoan(commitment, riskRating, maturity);
        ...
    }
    static Loan CreateTermLoan(double commitment, int riskRating, Date* maturity) {
   
        return new Loan(commitment, riskR
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值