Refactor To Pattern(一)

1  Chain Constructors
   Chain the constructors together to obtain the least duplicate code when you have multiple constructors that contain duplicate code
   现象:一个类中的多个构造函数含有相同的代码将会引起不必要的麻烦,当需要增加一个变量初始化时,有可能会漏掉一些构造函数
   方法:Chain Constructors是Refactoring的一种方式,其目的是简减少重复代码。当多个构造函数含有相同的代码时,考虑Extract Method方法将相同的代码提取出来。
   一般方法是:找出或构造一个Catch-All Constructor(包含所有构造信息)其它的构造函数调用该Catch-All构造函数
  示例:
  public Loan(float notional, float outstanding, int rating, Date expiry) {
    this.strategy = new TermROC();
    this.notional = notional;
    this.outstanding = outstanding;
    this.rating = rating;
    this.expiry = expiry;
  }

  public Loan(float notional, float outstanding, int rating, Date expiry, Date maturity) {
    this.strategy = new RevolvingTermROC();
    this.notional = notional;
    this.outstanding = outstanding;
    this.rating = rating;
    this.expiry = expiry;
    this.maturity = maturity;
  }

  public Loan(CapitalStrategy strategy, float notional, float outstanding, int rating,Date expiry, Date maturity) {
    this.strategy = strategy;
    this.notional = notional;
    this.outstanding = outstanding;
    this.rating = rating;
    this.expiry = expiry;
    this.maturity = maturity;
  }
  在上面三个构造函数中,第三个函数包含了所有要初始化的信息,将其当作Catch-All Constructor,第一第二个函数改为:
  public Loan(float notional, float outstanding, int rating, Date expiry) {
    this(new TermROC(),notional,outstanding,rating,expiry,null);
  }
 
  public Loan(float notional, float outstanding, int rating, Date expiry, Date maturity) {
    this(new TermROC(),notional,outstanding,rating,expiry,maturity);
  }
 

2. Replace Multiple Constructors with Creation Methods
   Too much constructors in a class make it hard to decide which constructor to call during development. You may use Replace the constructors with intention-revealing Creation Methods that return object instances.
   过多的构造函数难于决定该调用哪一个,可以通过Creation Methods创建对象实例并返回该对象实例。
   例如:
    public class Loan {
      private static String TERM_LOAN = "TL";
      private static String REVOLVER = "RC";
      private static String RCTL = "RCTL";
      private String type;
      private CapitalStrategy strategy;
      private float notional;
      private float outstanding;
      private int customerRating;
      private Date maturity;
      private Date expiry;
   
      public Loan(float notional, float outstanding, int customerRating, Date expiry) {
        this(TERM_LOAN, new TermROC(), notional, outstanding,customerRating, expiry, null);
      }
      public Loan(float notional, float outstanding, int customerRating, Date expiry,Date maturity) {
        this(RCTL, new RevolvingTermROC(), notional, outstanding, customerRating,expiry, maturity);
      }
   
      public Loan(CapitalStrategy strategy, float notional, float outstanding,
                  int customerRating, Date expiry, Date maturity) {
        this(RCTL, strategy, notional, outstanding, customerRating,expiry, maturity);
      }
      public Loan(String type, CapitalStrategy strategy, float notional,
                  float outstanding, int customerRating, Date expiry) {
        this(type, strategy, notional, outstanding, customerRating, expiry, null);
      }
   
      public Loan(String type, CapitalStrategy strategy, float notional,
                  float outstanding, int customerRating, Date expiry, Date maturity) {
        this.type = type;
        this.strategy = strategy;
        this.notional = notional;
        this.outstanding = outstanding;
        this.customerRating = customerRating;
        this.expiry = expiry;
        if (RCTL.equals(type))
          this.maturity = maturity;
      }
    }
   以上的5个构造函数中,并没有重复的代码,5个相似的构造函数使得客户端不知道该如何去调用这些构造函数。通过重构用清晰而易于理解的Creation Methods来代替以上构造函数。
   步骤:
   1). 找出Catch-All Constructor, 将Catch-All Constructor设置为protected或private访问限制
   2). For every type of object that can be created using one of the many constructors, create an
intention-revealing Creation Method.对每一个构造函数, 用一个清晰易于理解的Creation Method代替。
   3). 将客户端使用构造函数创建对象的地方用Creation Method代替
  
   示例类的构造函数可以创建以下的对象
 a Term Loan with default capital strategy
 a Term Loan with custom capital strategy
 a Revolver with default capital strategy
 a Revolver with custom capital strategy
 an RCTL with default capital strategy
 an RCTL with custom capital strategy
   分别用Creation Method方法替代以上构造函数
   重构的类代码如下:
    public class Loan {
        private static String TERM_LOAN = "TL";
        private static String REVOLVER = "RC";
        private static String RCTL = "RCTL";
        private String type;
        private CapitalStrategy strategy;
        private float notional;
        private float outstanding;
        private int customerRating;
        private Date maturity;
        private Date expiry;
       
        //Catch-All Constructor
        protected Loan(String type, CapitalStrategy strategy, float notional,
            float outstanding, int customerRating, Date expiry, Date maturity) {
            this.type = type;
            this.strategy = strategy;
            this notional = notional;
            this.outstanding = outstanding;
            this.customerRating = customerRating;
            this.expiry = expiry;
            if (RCTL.equals(type)
                this.maturity = maturity;
        }
       
        public static Loan newTermLoan(float notional, float outstanding, int customerRating,Date expiry) {
            return new Loan(TERM_LOAN, new TermROC(), notional, outstanding, customerRating,expiry, null);
        }
       
        public static Loan newTermWithStrategy(CapitalStrategy strategy, float notional,
                                                float outstanding, int customerRating, Date expiry) {
            return new Loan(TERM_LOAN, strategy, new TermROC(), notional, outstanding,
                            customerRating, expiry, null);
        }
       
        public static Loan newRevolver(float notional, float outstanding, int customerRating,Date expiry) {
            return new Loan(REVOLVER, new RevolverROC(), notional, outstanding,customerRating, expiry, null);
        }
       
        public static Loan newRevolverWithStrategy(CapitalStrategy strategy, float notional,
                                                    float outstanding, int customerRating, Date expiry) {
            return new Loan(REVOLVER, strategy, new RevolverROC(), notional, outstanding,
                            customerRating, expiry, null);
        }
       
        public static Loan newRCTL(float notional, float outstanding, int customerRating,
                                    Date expiry, Date maturity) {
            return new Loan(RCTL, new RCTLROC(), notional, outstanding,customerRating, expiry, maturity);
        }
       
        public static Loan newRCTLWithStrategy(CapitalStrategy strategy, float notional,
                                    float outstanding, int customerRating, Date expiry, Date maturity) {
            return new Loan(RCTL, strategy, new RevolverROC(), notional, outstanding,
                            customerRating, expiry, maturity);
        }
    } 

3 Encapsulate Subclasses with Creation Methods
适用性:Subclasses implement a common interface but are constructed in diverse ways
方法:Encapsulate the subclasses with intention-revealing Creation Methods in the base class
动机:隐藏子类实现
个人认为,该重构像Abstractor Factory Pattern. 通过Creation Method代替构造函数返回对象实例。有利于隐藏子类实现。
Abstract Factory通过Factory创建对象实例,而Encapsulate subclasses with Creation Methods将构造对象的函数置于基类中。

4 Extract Creation Class
适用性:Too many Creation Methods on a class obscure it's primary responsibility类中过多的Ceation Methods,不清楚其主要的责任。
方法:Move the Creation Methods for a related set of classes to one Creation Class将一系列相关类的Creation Method移到一个Creation Class中。
动机:该方法本质上来说是Extract Class. 一个类中含有大量的Creation Methods, 使人分不清该类的主要责任是什么。将这些Creation Method提取为一个类(类似于Abstract Factory).
备注:Creation Class与Abstract Factory不同点在于Creation Class创建对象是静态的,而Abstract Factory是运行时动态创建一系列对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值