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

Возьмем в качестве примера синтаксис Java, хотя сам вопрос не зависит от языка. Если следующий фрагмент кода принимает объект MyAbstractEmailTemplate в качестве входного аргумента в методе setTemplate, класс MyGateway будет тесно связан с объектом MyAbstractEmailTemplate, что уменьшает возможность повторного использования класса MyGateway .

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

Таким образом, если мы используем только примитивный тип данных (или даже простой XML в веб-сервисе) в качестве ввода / вывода метода, кажется, что проблема связи больше не существует. Так что ты думаешь?

public class MyGateway {

    protected MyAbstractEmailTemplate template;

    public void setTemplate(MyAbstractEmailTemplate template) {
        this.template = template;
    }
}

Ответы [ 6 ]

4 голосов
/ 19 мая 2010

Довольно сложно понять, о чем вы на самом деле спрашиваете, но путь ввода всего для Object не приводит к слабой связи , потому что вы ничего не можете сделать с вводом без понижения, что нарушить принцип замены Лискова .

В крайнем случае это приводит вас сюда:

public class MyClass
{
    public object Invoke(object obj);
}

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

3 голосов
/ 19 мая 2010

Имя MyAbstractEmailTemplate заставляет меня поверить, что вы говорите об абстрактном классе.

Вы должны всегда программировать против интерфейсов, поэтому вместо MyGateway зависит от MyAbstractEmailTemplate, оно должно зависеть от EmailTemplate интерфейса, где MyAbstractEmailTemplate implements EmailTemplate. Затем вы можете передавать свои пользовательские реализации по своему усмотрению, без дальнейшей тесной связи.

Объедините это с DI, и вы получите довольно приличное решение.

Не совсем уверен, что вы имеете в виду под "интерфейс по-прежнему жесткий", но, очевидно, вы должны разработать свой интерфейс таким образом, чтобы он обеспечивал необходимую вам функциональность.

1 голос
/ 19 мая 2010

MyGateway должен предполагать что-то о входах. Даже если бы он использовал XML, он должен был бы предположить что-то о структуре и содержании XML. Сцепление не является злом само по себе; выражает договор между двумя частями кода. Часто повторяемый совет избегать тесной связи просто говорит о том, что связь должна выражать суть контракта, не больше и не меньше. Передача определенного типа (особенно типа интерфейса) является очень хорошим способом достижения этого баланса.

0 голосов
/ 19 мая 2010

s Проблема в том, что я могу сказать, что лучшее, что может предложить Java, - это интерфейсы, и люди начинают понимать, что они слишком жесткие. Было бы интересно использовать что-то наподобие того, что написано на языке Go, что позволяет гибко проверять все методы интерфейса, присутствующие в типе, вам не нужно явно указывать реализацию какого-либо интерфейса. Нам также нужно что-то лучше, чем интерфейсы для определения ограничений - возможно, какие-то контракты. Другое дело, эволюция интерфейса.

0 голосов
/ 19 мая 2010

Первая проблема, с которой вы столкнетесь, заключается в том, что многие типы просто не могут быть представлены примитивным типом данных (проблема Java в том, что вообще существуют примитивные типы.)

Связь должна быть уменьшена с помощью правильной иерархии наследования. Что значит правильно? Метод должен принимать именно ту часть интерфейса в качестве необходимого параметра. Не более не менее.

Ведь вы не сможете избежать зависимостей. Методы должны знать, что они могут делать со своим вводом или иметь возможность делать предположения (см. Концепции C ++) о возможностях ввода.

0 голосов
/ 19 мая 2010

ИМХО, по сути, нет ничего плохого в использовании объектов (с маленькой заглавной буквой, а не Object с) в качестве параметров метода и / или членов класса. Да, они создают зависимости. Вы можете управлять этим (по крайней мере) двумя способами:

  • признают, что, создавая эту зависимость, два класса становятся тесно связанными. Это вполне уместно во многих случаях, когда два (или более) класса фактически образуют компонент , который сам по себе является значимой единицей повторного использования, и его части могут не иметь большого смысла или быть взаимозаменяемыми.
  • если имеется несколько взаимозаменяемых кандидатов для параметра метода, это очевидные кандидаты для формирования иерархии классов . Затем вы программируете интерфейс и можете передать любой метод любого класса, реализующего этот интерфейс, в качестве параметра для вашего метода.
    Обратите внимание, что фраза "существует несколько взаимозаменяемых кандидатов на параметр метода" перефразирование принципа замены Лискова , который является основой полиморфизма.
  • на некоторых языках, например C ++, третий способ будет использовать шаблоны. Тогда вам не нужен общий интерфейс, только конкретные методы / члены должны быть разрешены при создании экземпляра шаблона. Однако, поскольку создание экземпляров происходит во время компиляции, это полностью статическое связывание.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...