2017-01-28 21 views
3

Я читал о ТВЕРДЫХ принципах, и я остановился здесь на «принцип инверсии зависимостей» что означает, что объекты должны прошли уже экземпляр для пыльников объекта, что означает состав не может быть применен с зависимостей инверсии принцип прав? или что-то мне не хватает? ОБНОВЛЕНИЕ ************************************************ ** предположим, у вас есть класс, и этот класс имеет атрибут, который является ссылкой на объект пыльников, мы имеем 2 решение (для меня):.Dependency принцип инверсии и состав

  1. Создать объект вне класса и передать его к классу (Зависимость)
  2. Создайте объект внутри класса it self (состав).

спасибо.

+0

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

+0

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

+0

@FrankPuffer можно использовать композицию, используя инъекцию зависимостей? – justsomedev

ответ

6

Ваше замешательство исходит из вашего понимания композиции. Объект, принадлежащий другому, зависит от времени жизни объекта-владельца. Это не означает, что вам нужно создать принадлежащий ему объект внутри класса владельца.

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

Пример: enter image description here

На картинке выше вы имеете класс клиента, который использует класс Server. Допустим, что это композиция, и у Клиента есть атрибут типа Server.

Если вы создаете экземпляр класса сервера внутри класса клиента, он может выглядеть следующим образом:

public class Client { 
    private Server server; 

    public Client(){ 
     this.server = new Server(); 
    } 
} 

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

public class Client { 
    private AnotherServer anotherServer; 

    public Client(){ 
     this.anotherServer = new AnotherServer(); 
    } 
} 

Это показывает, что класс Client сильно зависит от класса Server.

Чтобы легко изменить используемую реализацию Сервера и, таким образом, изменить поведение Клиента, было бы лучше составить клиент из абстракций (абстрактных классов или интерфейсов). Это означает, что вы не можете создать нужный объект в собственном классе, потому что вы можете создавать только конкретные классы. Создание классов означает вызов конструктора и зависящий от этого класса, который был создан.

Лучший способ достижения композиции (- Клиент состоит из сервера) - путем инъекции его через метод сеттера или конструктор. Подобно этому вы можете скрыть классы реализации за интерфейсом.

Пример: enter image description here

На втором рисунке мы защитить клиента от знания о конкретной реализации сервера. Это зависит только от интерфейса сервера. Эта зависимость не настолько драматична, потому что Клиент определяет интерфейс. Он решает о необходимой функции интерфейса сервера. Чтобы указать, что интерфейс для серверов принадлежит клиенту, он называется «ClientServer».

Для составления вашего Клиента вам необходимо создать конкретные классы для интерфейса ClientServer вне класса и ввести его через конструктор или метод setter.

... 
FirstServer first = new FirstServer(); 
Client client = new Client(first); 

client.setServer(new SecondServer()); 
... 

Нравится программа? Поделись с друзьями!

Этот механизм называется принципом инверсии зависимостей (DIP). Но почему? Класс Client по-прежнему зависит от интерфейса сервера. Если интерфейс изменяется, Клиент также должен измениться. Да, это правильно. Но Клиент решает, какие функции ему нужны в этом интерфейсе. Поэтому обычно интерфейс изменяется, когда Клиент говорит, что его нужно изменить. Интерфейс изменяется, поскольку Клиент изменяется.

Поскольку конкретные серверы «FirstServer» и «SecondServer» реализуют интерфейс ClientServer, они также зависят от этого интерфейса. И поскольку наследование является более сильной зависимостью, чем состав, конкретные классы серверов в большей степени зависят от интерфейса, чем от класса Client.

Именно поэтому зависимости инвертированы. Конкретные классы серверов теперь зависят от «Client-ClientServer» -колонтера.

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

+0

Если мне нужно использовать класс из .NET Framework. Должен ли я вводить его в класс? – VansFannel

1

Взятые from Wikipedia:

A. Модули высокого уровня не должны зависеть от модулей низкого уровня. Оба должны зависеть от абстракций.

B. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

И вы сказали:

что означает объекты должны прошли уже экземпляр к другому объекту

Dependency Inversion принцип не имеет ничего против деталей реализации программ, как класса конструкторами , которые предназначены для инициализации построенного объекта.

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

+0

Было бы здорово узнать, почему я получил нижний план, чтобы улучшить свой ответ. Благодарю. –

 Смежные вопросы

  • Нет связанных вопросов^_^