Должен ли я загружать данные моего Java-объекта при создании или явно через вызов метода? - PullRequest
1 голос
/ 10 марта 2010

Это вопрос дизайна. Я пытаюсь выбрать между двумя реализациями.

Чтобы правильно объяснить это, мне нужен пример. Итак, ради примера:

У меня есть класс, который генерирует отчет о, скажем, определенных значениях фондового рынка в определенный день. Я создаю объект StockMarketReportGenerator, передавая ему сегодняшнюю дату, и он генерирует отчет на основе сегодняшних рыночных ценностей.

StockMarketReportGenerator "имеет" StockMarketData объект. Цель объекта StockMarketData состоит в том, чтобы содержать все значения фондового рынка, которые хранятся в таблице (вероятно, называемой StockMarket :)) в базе данных, и некоторые дополнительные значения, рассчитанные на основе данных таблицы. Он имеет частные методы, которые соединяются с базой данных, извлекают данные, выполняют необходимые вычисления и сохраняют окончательные значения в переменных-членах объекта. (Затем у него есть методы-получатели для предоставления этих значений, но нет методов-установщиков.) Класс StockMarketData в основном является «держателем» для значений данных фондового рынка. У меня есть одна центральная функция, которая называется что-то вроде "calculateStockMarketData()", которая вызывает все эти частные вспомогательные методы и устанавливает объект. (Я знаю, что вся эта обработка действительно может быть легче обработана такой средой, как Hibernate; но было принято решение сделать это вручную, так как это очень маленький, несколько временный проект и не стоит установки.)

У меня такой вопрос - из моего класса ReportGenerator мне нужен только объект StockMarketData для доступа к его свойствам / переменные-члены - пост-обработка и пост-вычисления. Что означает, что на самом деле, я хочу, чтобы объект был предварительно заполнен с данными. И поэтому я сохраняю метод calculateStockMarketData закрытым и вызываю его автоматически из StockMarketData конструктор. Но я чувствую себя несколько неловко из-за того, что выполняю всю свою обработку в конструкторе, а затем не использую общедоступные методы. Это недостаток дизайна? Или это действительно самый логичный способ сделать это? В принципе, какая из следующих 2 реализаций лучше?

1) (Моя текущая реализация) Сделайте центральный метод calculateStockMarketData() закрытым и вызовите его из конструктора метода StockMarketData (передавая сегодняшнюю дату), чтобы всякий раз, когда у вас есть объект StockMarketData, он уже был заполнен. Поэтому все, что мне нужно из класса ReportGenerator, прежде чем я начну использовать свойства объекта, это строка:

StockMarketData myData = new StockMarketData(someDate);

2) Сделайте центральный метод calculateStockMarketData() общедоступным, чтобы для установки объекта StockMarketData вам нужно было явно вызвать метод. Так что из класса ReportGenerator я бы написал:

StockMarketData myData = new StockMarketData(someDate);
myData.calculateStockMarketData();

Первый мне кажется лучшим дизайном, тем более что нет возможности использовать свойства объекта до их инициализации. Но я также не уверен в стандартах выполнения большого количества кода из конструктора ... Что мне выбрать?

Ответы [ 4 ]

7 голосов
/ 10 марта 2010

Мартин Фаулер написал хорошее эссе о внедрении зависимостей (Конструктор против внедрения Сеттера) . Его совет - «насколько это возможно, создавать действительные объекты во время строительства».

IMO, Лучше по возможности создавать допустимые объекты, потому что это облегчает чтение / наблюдение за поведением кода, поскольку вы можете предположить, что объекты были построены правильно, и у вас меньше ошибок, связанных с тем, что объекты не заполнено правильно. Проблема внедрения сеттера и конструктора отличается от того, о чем вы спрашиваете, и в этом вопросе, где выполнять вашу бизнес-логику. Я думаю, что лучше всего использовать конструктор для создания допустимого объекта, а затем выполнить фактическую бизнес-логику в другом публичном методе (ваш # 2), чтобы создание объекта могло происходить в другое время, чем фактическая бизнес-логика.

1 голос
/ 10 марта 2010

Я бы пошел с номером 2, особенно если есть возможность добавления методов в класс, которые не полагаются на эти данные.

С другой стороны, если вы считаете, что класс находится в недопустимом состоянии без заполненных данных, вы должны сделать это при создании.

1 голос
/ 10 марта 2010

Я всегда загружаю явно, постстроение.

Вызов базы данных из конструктора может затруднить отладку, сделать более хрупким, негибким кодом и вызвать проблемы с производительностью в случае изменения использования вами объекта.

0 голосов
/ 10 марта 2010

Хорошей практикой является не выполнять много кода внутри конструктора.

...