2013-03-23 24 views
1

我正在使用Builder模式来更容易地创建对象。但是,标准构建器模式示例不包含错误检查,这是我的代码中需要的。例如,Simulator对象中的accessibilitydemandMean阵列应具有相同的长度。代码的简要框架如下所示:带有错误检查的生成器模式:是否有可能/可取?

public class Simulator { 
    double[] accessibility; 
    double[] demandMean; 

    // Constructor obmitted for brevity 

    public static class Builder { 
     private double[] _accessibility; 
     private double[] _demandMean; 

     public Builder accessibility(double[] accessibility) { 
      _accessibility = accessiblity.clone(); 
      return this; 
     } 

     public Builder demandMean(double[] demandMean) { 
      _demandMean = demandMean.clone(); 
      return this; 
     } 

     // build() method obmitted for brevity 
    } 
} 

作为另一示例,在一个推广优化问题,有各种促销车辆(例如传单,显示器)和促进模式,它们是一组促销的车辆(例如没有,只有传单,只显示,传单和显示)。当我创建Problem时,我必须定义可用的车辆集合,并检查促销模式是否使用这些车辆的一个子集,而不是其他一些无法使用的车辆,以及促销模式不相同(例如, t两个促销模式都是“传单专用”)。代码的简单框架如下图所示:

public class Problem { 
    Set<Vehicle> vehicles; 
    Set<PromoMode> promoModes; 

    public static class Builder { 
     Set<Vehicle> _vehicles; 
     Set<PromoMode> _promoModes; 
    } 
} 

public class PromoMode { 
    Set<Vehicle> vehiclesUsed; 
} 

我的问题有以下几点:

  1. 是否有解决这种情况的标准方法?
  2. 在调用build()方法时,应该在构造函数还是构建器中进行错误检查?
  3. 为什么这是“正确”的方法?

回答

2

当您在创建对象时需要保持不变量时,如果任何参数违反了不变量,则停止构建。这也是一种快速失败的方法。
当您拥有大量参数时,构建器模式有助于创建对象。
这并不意味着你不做错误检查。
只想尽快抛出一个合适的RuntimeException作为参数侵犯的对象不变

+0

这是有道理的。谢谢! – 2013-03-24 01:24:56

0

“正确”的做法真的取决于形势 - 如果它是无效的构建不同大小的阵列,我会说这是更好地在施工中处理,无效状态越早发现越好。

现在,如果您可以更改数组并放入不同的数组中 - 那么在调用它时可能会更好。

1

您应该使用构造函数,因为它更好地遵循单责任原则。制造商不负责检查不变量。真正的工作是收集构建对象所需的数据。
此外,如果您决定稍后更改该类以具有公共构造函数,则不必移动该代码。

你绝对不应该检查setter方法中的不变量。这有几个好处:
*您只需要检查ONCE
*在例如您的代码的情况下,由于您在不同的时间添加两个数组,因此无法提前检查不变量。您不知道您的用户将添加它们的顺序,因此您不知道应该使用哪种方法执行检查。

除非您的构建器中的setter执行一些强烈的计算(这种情况很少出现 - 一般来说,如果需要进行某种计算,它应该在构造函数中发生),但对失败没有帮助早期“,尤其是像你这样的流利建设者只使用1行代码来构建对象,所以任何try块都会围绕整条线。

相关问题