Конструктор Инъекция, дизайн для тестируемости - PullRequest
1 голос
/ 18 декабря 2009

У меня есть этот код (вы, вероятно, можете игнорировать, что это код Swing), но в моем конструкторе обычно слишком много аргументов Должен ли я использовать класс bean-компонента модели, а затем передать этот объект в конструктор?

public BrowserFrame(final JTextField url, final JTextArea response, final JTextField command, final JButton actionButton) {

    this.urlField = url;
    this.responseArea = response;
    this.commandField = command;
    this.actionButton = actionButton;

}     

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

Но, по словам Миско, это тоже кодовый запах.

http://misko.hevery.com/code-reviewers-guide/

"Объекты передаются, но никогда не используются напрямую (используются только для получения доступа к другим объектам)"

Ответы [ 6 ]

2 голосов
/ 18 декабря 2009

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

0 голосов
/ 18 декабря 2009

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

Я думаю, что переоценка схемы компоновки объектов может быть более полезной в долгосрочной перспективе, например, перераспределение абстракции так, чтобы BrowserFrame состоял из Sections (например, AddressSection, ActionSection, InputSection, FeedbackSection и т. Д.) Вместо отдельные объекты Swing,

Вы можете также изменить рефакторизацию чрезмерной параметризации конструкции BrowserFrame, используя вместо этого подклассификацию.

0 голосов
/ 18 декабря 2009

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

Если вопрос «У этого класса слишком много забот?» перестаньте спрашивать "Каковы признаки того, что у класса слишком много забот?" Почему бы не спросить: «Что беспокоит этот класс?» Если ответ прост: «Он объединяет несколько элементов формы в одно представление», что я (и, как следствие, другие стороны, просматривающие ваш код) логично предположил бы, то перестаньте беспокоиться о косметике, такой как конструкторы. Это достаточно очевидно в этом случае. Добавление большего количества классов просто запутает это.

0 голосов
/ 18 декабря 2009

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

0 голосов
/ 18 декабря 2009

BrowserFrame указывает на то, что вы расширяете класс (JFrame) там, где он вам не нужен. Это плохо.

Я склонен иметь слой макета около слоя JComponent / view.

class ThingView {
    [...]
    public JTextField /*or JComponent*/ createURL() { /* or geURL */
        return new JTextField(...); // Or from a field if using get.
    }
    [...]
}

class ThingLayout {
    private final ThingView view; 
    [...]
    public JPanel createBrowsePanel() {
        JPanel panel = new JPanel();
        [...]
        panel.add(view.createURL());
        [...]
        return panel;
    }
}
0 голосов
/ 18 декабря 2009

Поскольку вы хотите очистить свой код и улучшить его тестируемость, возможно, вы можете пойти на инициализацию сеттера. Таким образом, у вас будет более чистый конструктор для вашего объекта. Также проще протестировать код, если вы можете установить только «некоторые» из его полей, а не все. Тесты становятся более читабельными.

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

...