这是一个设计问题。我正在尝试在两个实现之间做出决定。
为了正确解释这个,我需要一个例子。所以,为了举例:
我有一个班级可以生成一份报告,比如某个特定日子的某些股票市场价值。我创建了一个StockMarketReportGenerator
对象,将其传递给今天的日期,并根据当前的市场价值生成一份报告。
StockMarketReportGenerator
“有一个”StockMarketData
对象。在StockMarketData
对象的目的是包含所有存储在一个表中的股票的市场价值在数据库中(可能称为股市:)),并从表中数据计算的一些其它值。它具有与数据库连接的私有方法,检索数据,进行必要的计算,并将最终值存储在对象的成员变量中。 (然后它有getter方法来公开这些值,但没有setter方法。)StockMarketData
类基本上是股票市场数据值的“持有者”。我有一个称为“calculateStockMarketData()
”的中心函数,它调用所有这些私有帮助器方法并设置对象。 (我知道这一切的处理真的可以更容易地通过如Hibernate框架来处理;但作出决定,做手工,因为它是一个非常小的,有些临时的项目和不值得的设置)
我的问题是 - 从我的ReportGenerator
课程中,我只需要StockMarketData
对象才能访问它的属性/
成员变量 - 后处理和后计算。这意味着,我想要预先填充对象
有数据。因此,我将calculateStockMarketData
方法保密,并从StockMarketData
自动调用它
构造函数。但是我对在构造函数中进行所有处理然后没有任何公共方法感到有些不安。这是一个设计缺陷吗?或者这是最合乎逻辑的方式吗?基本上,以下哪两种实现更好?
1),(我的当前实现)使中央calculateStockMarketData()
方法私人和从StockMarketData
方法构造函数调用它(通过今天的日期),所以,只要你有一个StockMarketData
对象,它已经填满了。因此,在开始使用对象属性之前,我需要ReportGenerator
类的所有内容是行:
StockMarketData myData = new StockMarketData(someDate);
2)将中心calculateStockMarketData()
方法设为公共,这样为了设置StockMarketData
对象,您需要显式调用该方法。所以从ReportGenerator
类我会编码:
StockMarketData myData = new StockMarketData(someDate);
myData.calculateStockMarketData();
第一个让我觉得更好的设计,特别是因为在初始化之前不可能使用对象属性。但是我也不确定从构造函数执行大量代码的标准......我应该选择哪个?
答案 0 :(得分:7)
Martin Fowler撰写了一篇关于dependency injection (Constructor vs. Setter injection)的好文章。他的建议是“尽可能地在施工时创造有效物品”。
IMO,如果可能的话,最好构造有效的对象,因为它可以更容易地读取/观察代码的行为,因为你可以假设对象是正确构造的,并且你没有与对象相关的bug更少填写正确。 setter与构造函数注入的问题不同于您所询问的问题,这是执行业务逻辑的位置问题。我认为最好使用构造函数来创建有效对象,然后在另一个公共方法(#2)中执行实际业务逻辑,这样对象的构造可以在与实际业务逻辑不同的时间发生。
答案 1 :(得分:1)
我会选择2号,特别是如果有可能在类中添加不依赖于那些数据的方法。
另一方面,如果您认为该类在没有填充数据的情况下处于无效状态,则应该在构造时进行。
答案 2 :(得分:1)
我总是在施工后明确加载。
从构造函数调用数据库可能会导致调试困难,代码更脆弱,代码更不灵活,并且如果对象的使用发生更改,则会导致性能问题。
答案 3 :(得分:0)
一个好的做法是不在构造函数中执行大量代码。