通过构造函数传递的对象引用

问题描述:

我构建了一个相对较大的面向对象程序。我有一个名为AerodynamicCalculator的课程,它执行许多计算并将结果分发给系统。我主要担心的是我的构造函数签名越来越大,因为我添加了mor参数。通过构造函数传递的对象引用

如下图所示,我已经有9个对象引用被传递给这个构造函数,但是我需要另外7个对象引用。我正确地创建这个对象吗?我的理解是,您将关联的对象引用传递给构造函数,并将类的局部变量分配给对象引用。如果是这种情况,让所有需要的对象正确初始化我的类的唯一方法是将它们传递给构造函数,这会导致很长的签名。

public AreodynamicCalculator(AircraftConfiguration config, AileronOne aOne, 
     AileronTwo aTwo, ElevatorOne eOne, ElevatorTwo eTwo, Rudder r, 
     Rudder rr, RateGyros rG) { 
    // ... 
} 

对此方法的任何建议将非常有帮助,在此先感谢。

+0

将提出各种策略,并可能是您去的最佳方式;但这可能表明你的班级正试图做太多的事情,需要分解成更小的部分。 – 2012-04-19 15:38:51

+0

这不是禁止的。这是做到这一点的一种方式。还有其他方法可以做到这一点,但最终都会归结为系统的特定体系结构,它会“告诉”您创建系统的最佳方式。这个问题可能会因为范围过宽而关闭。 – Th0rndike 2012-04-19 15:40:26

+0

该类实际上只计算5个变量,但必须将这些变量分配给7个对象。如何从计算中使用的变量中提取出我在原始文章中显示的对象。所以类dosnt做了这么多,但它作为一个吸气剂,系统计算器和计算结果分配器。 – 2012-04-19 15:44:44

如前所述 - 这可能是您的班级做得太多的迹象,但是,这个问题有一个常用的“解决方案”。

构建器模式通常用于这种情况,但是当您有许多具有不同参数的构造函数时,构建器也非常有用,因为它使参数的含义更清晰,特别是在使用布尔文字时。

这里是建造者模式,这种工作方式是这样的:

AreodynamicCalculator calc = AreodynamicCalculator.builder() 
    .config(theAircraftConfiguration) 
    .addAileron(aileronOne) 
    .addAileron(aileronTwo) 
    .addElevator(elevatorOne) 
    .addElevator(elevatorTwo) 
    .addRudder(rudderOne) 
    .addRudder(rudderTwo) 
    .build() 

内部,生成器将存储所有这些领域,并在build()被调用时,它将调用一个(现在的私立)构造函数需要这些字段:

class AreodynamicCalculator { 
    public static class Builder { 
     AircraftConfiguration config; 
     Aileron aileronOne; 
     Aileron aileronTwo; 
     Elevator elevatorOne; 
     Elevator elevatorTwo; 
     ... 

     public Builder config(AircraftConfiguration config) { 
      this.config = config; 
      return this; 
     } 

     public Builder addAileron(Aileron aileron) { 
      if (this.aileronOne == null) { 
       this.aileronOne = aileron; 
      } else { 
       this.aileronTwo = aileron; 
      } 
      return this; 
     } 

     // adders/setters for other fields. 

     public AreodynamicCalculator build() { 
      return new AreodynamicCalculator(config, aileronOne, aileronTwo ...); 
     } 
    } 

    // this is the AircraftConfiguration constructor, it's now private because 
    // the way to create AircraftConfiguration objects is via the builder 
    // 
    private AircraftConfiguration config, AileronOne aOne, AileronTwo aTwo, ElevatorOne eOne, ElevatorTwo eTwo, Rudder r, Rudder rr, RateGyros rG) { 
     /// assign fields 
    } 
} 
+0

感谢您的帮助和努力。我很感激。是否有任何表现,但更重要的是这样做的安全原因? – 2012-04-19 15:52:20

+0

至于性能处罚 - 呃,你需要分析应用程序。现在有两个对象(可能大小相同)创建而不是一个(构建器对象和构建对象),并且将收集构建器实例。安全,我不确定你的意思。如果构建器没有完全填充(调用的构造器太少),那么它应该抛出异常(我将使用RuntimeException子类) – daveb 2012-04-19 15:56:08

与使用daveb响应中建议的构建器模式类似,可以使用Spring之类的依赖注入框架。

+0

DI将帮助注入不同的实现。它无助于防止传递给构造函数的引用太多。 – mrab 2012-04-19 15:44:36

+0

取决于您是否使用构造函数注入或方法注入(使用属性设置器)。你可以用春天做。 – 2012-04-19 17:34:45