На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! В разделе обсуждаются следующие темы:
1) Процесс разработки программного обеспечения.
2) Определение требований к программному обеспечению.
3) Составные части и процесс проектирования (см. Шаблоны проектирования).
4) Документирование программного продукта(проекта).
5) Руководство разработкой программного обеспечения.
6) Проектирование пользовательского интерфейса.
7) Контроль версий проекта (см. Управление версиями в Subversion, Стратегии использования svn).
Модераторы: ElcnU
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Inversion of Control , не могу понять
    Привет!

    Несколько часов потратил на попытки понять что же такое inversion of control, так и не смог :-)

    Цитата
    In computer programming, Inversion of control (IoC) is an abstract principle describing an aspect of some software architecture designs in which the flow of control of a system is inverted in comparison to procedural programming.
    Читаю так: IoC - это абстрактный принцип, описывающий особенность некоторых дизайнов архитектуры ПО, в которых "порядок передачи управления" инвертирован относительно оного в процедурном программировании. Не понимаю.

    1. Начнём с того, что IoC - это приинцип. Принцип, в моём понимании, это утверждение вида "в ситуации X надо (можно, следует) делать Y". Возьмём, например, LSP:
    "It states that, in a computer program if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may be substitutes for objects of type T), without altering any of the desirable properties of that program (correctness, task performed, etc.).". Читаю как: он утверждает, что если S - это подтип T, тогда объекты типа T могут быть заменены объектами S. Т.е. к LSP моё понимание "принципа" подходит. В случае LSP можно сказать, выполняется он (принцип) или нет. Как определить, выполняется ли IoC?
    2. Известно, что у IoC формального определения нет. Известно, что IoC определяется как разница между фреймворком и библиотекой. Разницу между фреймворком и библиотекой я понимаю: абстрактное решение для всей задачи vs. конкретные решения для её частей.

    Помогите, пожалуйста, разобраться :-)
      По-моему это то же разделение на интерфейс и имплементацию, токо сказанное по новому :)

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

        Добавлено
        Ну или более скучное, но тоже понятное непонятное описание. Как его не найти было?.. :unsure:
        Сообщение отредактировано: ss -
          Спасибо за ответы!

          Машина,
          Т.е. если я использую указатели на функции в коде на Си (например, предикат для сортировки), это уже получается "удовлетворение принципа IoC"?

          ss,
          Огромное спасибо за наглядный пример :-) Википедию, конечно, тоже читал и русскую и английскую.


          Попытаюсь уточнить проблему. Я не понимаю общего смысла IoC. Нужна формулировка, а не описание свойств. Насколько будет верно, если я скажу так:

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

          ?

          Примеры:
          1. Думаю, мой пример с сортировкой и предикатом - правильный. Сортировка отвечает только за перестановку элементов в случае, когда она знает что их нужно переставить, а решения по поводу правильности перестановки принимает какой-то внешний код, про который сортировка ничего не знает.
          2. Если про класс можно сказать, что он читает данные из базы и выводит их на консоль, база для него должна быть не базой, а "штукой, которая умеет интерпретировать sql и возвращать результаты запросов". Класс должен отвечать только за построение запросов и за получение/отображение результатов. Что там за база на самом деле он знать не должен, т.к. вполне может без этого обойтись.
            andyag

            Несколько часов потратил на попытки понять что же такое inversion of control, так и не смог :-)

            http://blog.byndyu.ru/2009/12/blog-post.html
              Ну вот же! Стоило чуть копнуть - и всё становится понятно.

              Читай дальше:
              Цитата
              In traditional programming the flow of the business logic is controlled by a central piece of code, which calls reusable subroutines that perform specific functions. Using Inversion of Control this "central control" design principle is abandoned. The caller's code deals with the program's execution order, but the business knowledge is encapsulated by the called subroutines.
              In practice, Inversion of Control is a style of software construction where reusable generic code controls the execution of problem-specific code. It carries the strong connotation that the reusable code and the problem-specific code are developed independently, which often results in a single integrated application.

              IoC, как ты уже заметил, это принцип. Он заключается в том, что вызывающая сторона знает только порядок вызова методов, но как работает конкретный метод она не знает, ибо обращается через интерфейс.
              А Dependency Injection - это один из способов следования IoC, способ отвязать caller'а от конкретной реализации.

              Некоторые статьи в русской википедии пишут дебилы. Ибо IoC > DI, а не как там преподносят.
                ss,
                У меня вообще складывается впечатление, что в инженерии ПО набралось слишком много слов типа IoC и DI, которые мало кто понимает, и поэтому каша такая. Тут теперь второй вопрос - где граница между IoC и SRP (single responsibility) :-)

                Rififi,
                Спасибо за интересную статью, но не стоит меня так цитировать, будто я идиот и не смог эту статью найти :-) Статья, несмотря на всю свою интересность, никак не связана с моей проблемой :-) Внимательнее читай вопрос. В статье нет ни определения, ни более-менее внятной теории, а как переписывать хреновый нетестируемый код в более-менее вменяемый - это другой вопрос, тут дело привычки.
                  andyag, да они какбэ не в одной плоскости находятся... Ты запросто можешь наплевать на SRP и яро следовать IoC, или наоборот, или оба сразу...
                  Что тебе, например, мешает зафигачить интерфейс навроде кухонного комбайна? Или ДеревяннаяНога + КоричневаяПластмассоваяСтолешница, в которой будет четыре указателя на ДеревяннуюНогу?
                    ss,
                    Ну вот смотри. Пишем чудовищный класс, который делает какие-то манипуляции с базой данных:
                    ExpandedWrap disabled
                      class DBManipulator // должен делать несколько запросов в несколько таблиц
                      {
                        private DBConnection connection;
                        public DBManipulator(string connectionString, DBConnectorEnum dbConnectorType) // внимание, говнокод :-)
                        {
                          if(dbConnectorType == MSSQL) { connection = new MsSqlConnection(connectionString); }
                          else if(dbConnectorType == MYSQL) { connection = new MySqlConnection(connectionString); }
                          else throw new WhatTheFuckIsYourDB();
                        }
                       
                        void doSomethingWithDB() { ... }
                      }


                    Вопросы:
                    1. Нарушается ли тут IoC? Почему?
                    2. Нарушается ли тут SRP? Почему?

                    Мои ответы:
                    IoC нарушается - мы принимаем решение по поводу того, через что подключаться к базе, хотя вообще говоря не наше это дело, наше дело - делать запросы. Для запросов нам достаточно просто иметь подключение к базе. Нам его надо иметь? Мы его будем иметь. Пусть кто-нибудь даст. Если бы в конструктор передавалось существующее подключение, это решило бы проблему. (это исходя из моего определения - всё ещё не уверен, насколько оно верное)
                    SRP нарушается - на классе 2 ответственности - "подключиться к базе", что-то "делать с базой". Избавляемся от "подключиться к базе" (т.е. берём решение для пункта 1), и... SRP тоже не нарушается.

                    В чём я неправ?
                      Да нет тут нарушения ИоКа - ты ж не обращаешься напрямую к методам конкретных коннекшнов, через интерфейс работаешь. Тут только СРП нарушен.
                        Цитата ss @
                        не обращаешься напрямую к методам

                        ExpandedWrap disabled
                                class DBManipulator // должен делать несколько запросов в несколько таблиц
                                {
                                  private DBConnection connection;
                                  public DBManipulator(string connectionString, DBConnectorEnum dbConnectorType) // внимание, говнокод :-)
                                  {
                                    //////////////////////////////////////////////////////////////////////////////////////////////////////
                                    if(dbConnectorType == MSSQL) { connection = MsSqlConnection.fromConnectionString(connectionString); } // ну вот такой он, этот MsSqlConnection
                                    //////////////////////////////////////////////////////////////////////////////////////////////////////
                                    else if(dbConnectorType == MYSQL) { connection = new MySqlConnection(connectionString); }
                                    else throw new WhatTheFuckIsYourDB();
                                  }
                                
                                  void doSomethingWithDB() { ... }
                                }

                        А так? Вообще говоря, я с тобой и по поводу старого примера не могу согласиться, любой конструктор - ни разу не интерфейсный метод, это деталь реализации.
                        Сообщение отредактировано: andyag -
                          Ну ок, вынесешь ты создание коннекшнов из конструктора, будешь указатель передавать... А где ты их создашь, коннекшны-то? Втам не будет нарушения ИоКа?
                          Жизнь - она, сука, не по книжке... Всегда во все парадигмы и идиомы уложиться не получится. Главное, когда на это напорешься, сильно не переживать.
                            У нас в скоупе был 1 этот класс, так что дальнейшая реализация не интересна :-) Будет там что-то типа читалки конфигов + предоставлялка подключений к базе.
                            По поводу теории - полностью согласен. Деньги в большинстве случаев вообще только за практику платят. Но это не повод не знать теорию :-)
                              ИМХО IoC определяется намного проще - это принцип, согласно которому мы пишем ПО так, что объекты "не падают с неба". Т.е. минимизируем кол-во new XXX().
                              Если объекту А нужна ссылка на объект Б, это не в его компетенции знать, где взять нужную ему ссылку и уж тем более создать объект Б руками (в реальной жизни же ничего само по себе не материализуется). Всё остальное уже логично вытекает из этого утверждения.

                              А интерфейсы и сокрытие реализации методов, в которые вы ударились - это ребята ООП :) Инкапсуляция.. IoC и интерфейсы никак не взаимосвязаны, вообще никак.
                              Сообщение отредактировано: deil -
                                Цитата deil @
                                А интерфейсы и сокрытие реализации методов, в которые вы ударились - это ребята ООП :) Инкапсуляция.. IoC и интерфейсы никак не взаимосвязаны, вообще никак.

                                Я бы сказал, что инкапсуляция (сокрытие внутренних полей и методов) и интерфейсы - это разные вещи :rolleyes:
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1014 ]   [ 15 queries used ]   [ Generated: 19.04.24, 00:56 GMT ]