Не скрывает ли информация об инъекции инъекции Spring?

Исходя из фона С++, мне нужно освоить сложность Java мира и его структуры. Глядя на структуру spring для DI, я с трудом полагая, что я должен сделать каждую функцию сеттера которые будут предметом публичного обсуждения. Разве это требование не нарушает принцип скрытия информации?

Конечно, я хочу, чтобы spring мог установить некоторые частные части моего классы, но я, конечно, НЕ хочу, чтобы каждый клиентский класс мог то же самое.

Что мне здесь не хватает?

Ответы

Ответ 1

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

Ответ 2

Я согласен с вашим мнением - почему я предпочитаю инъекцию конструктора.

Ответ 3

Вам (возможно) придется создать сеттер, который будет информировать вас о внешней стороне некоторых ваших внутренних деталей, но нет необходимости создавать геттер. Таким образом, вы раскрываете некоторую информацию, но не слишком много; это не очень полезно ни для чего, кроме его предназначения.

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

Ответ 4

Если вы используете аннотации spring (@Autowired), вы можете использовать DI-членов.

Если вы идете на развязку сцепления и (единицы измерения), на мой взгляд, пружины DI вырывают информацию, которая не должна быть скрыта.

Ответ 5

У меня был в основном тот же вопрос:

Инкапсуляция в возрасте фреймворков

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

Ответ 6

Никогда не используется @Autowired, мне нравится использовать параметры в конструкторах, но иногда трудно понять, что означают параметры, особенно если у вас много параметров - в этом случае я предпочитаю использовать подход "Builder" описанных в "Эффективной Java". Конструктор получает объект сборки (который имеет сеттеры) и строит себя с ним. Введенные атрибуты класса являются окончательными (неизменяемость), класс "Builder" содержит сеттеры, но не геттеры (ему не нужно, поскольку мы объявляем его внутренним классом класса, который строится), и нет необходимости в сеттерах для создания только для Spring:

<bean id="runnable" class="MyClass">
   <constructor-arg>
     <bean class="MyClass$Builder">
       <property name="p1" value="p1Value"/>
       <property name="p2" value="p2Value"/>
       <property name="p3" value="p3Value"/>
       <property name="p4" value="p4Value"/>
     </bean>
   </constructor-arg>
</bean>

Код класса:

public class MyClass {
   private final String p1;
   private final String p2;
   private final String p3;
   private final String p4;
   public MyClass(Builder builder) {
      this.p1 = builder.p1;
      this.p2 = builder.p2;
      this.p3 = builder.p3;
      this.p4 = builder.p4;
   }

   ...

   public static class Builder {
      private String p1;
      private String p2;
      private String p3;
      private String p4;
      public void setP1(String p1) {
         this.p1 = p1;
      }
      ... and so on
   }
}

Ответ 7

Я полагаю, что это компромисс. Вы уменьшаете жесткие зависимости, но вы потенциально можете разоблачить смелость вашей реализации. С помощью правильных абстракций вы можете уменьшить это также, но тогда вы увеличиваете сложность базы кода (например, имея общее "соединение", которое может быть соединением LDAP или SQL-соединением).

Лично я не думаю, что использование конструкторской инъекции помогает с этим, потому что оно более концептуально.

Мне нужно будет проверить @Autowire, tho '.

т

Ответ 9

Не согласен с тем, что Spring разрушает инкапсуляцию. Даже если у вас есть pojo, где вы получили и выставили на класс, а третья сторона потребляет вашу банку, все же шансы на то, что потребитель банки сделает то же самое, что возможно с конфигурацией Spring bean. (true для любого другого языка ООП)

Spring просто предоставляет способ, который может быть выполнен с помощью кода, и этот элемент управления выведен из кода (IOC).

Потребитель (подумайте, что другой программист использует вашу библиотеку), создает bean через конфигурацию Spring, но ваш код имеет контроль. Ни один орган не останавливает вас для проверки ввода данных, предоставленного пользователем (spring IOC framework также проходит через тот же код, который выполняется другим классом, вызывающим ваш сеттер) в setter.

public void setAge(int age) {
 if ( age < 0 ) {
   throw new AppException("invalid age!");
 }
 this.age=age;
}

Ответ 10

И это еще одна причина, по которой я предпочитаю Guice;) И Guice, и Spring реализуют спецификацию JSR 330 DI, но с Guice я могу вставлять в свои частные поля экземпляра без настроек, мне очень не нравится инъекция конструктора, поскольку было труднее рефакторинг. Это также просто намного больше печатает для меня не очень ценное по моему скромному мнению.

позже, Дин