Re[12]: своё vs. сторонее
От: Doc Россия http://andrey.moveax.ru
Дата: 15.10.13 06:23
Оценка:
Здравствуйте, IT, Вы писали:

Doc>>Как видим, зависимость никуда не делась, ибо value1 и value2 откуда-то должны браться.

IT>Это уже проблема вызывающего класса. У обсуждаемого класса зависимостей нет вообще.

Дай угадаю, с классом выше ты поступишь так же? Или ты пишешь библиотеки, состоящие из одного класса?

Кстати, а что делать будешь, если нужны будут методы _service, в который нужно передать аргументы (которые скрыты внутри самого класса)?
Re: своё vs. сторонее
От: Аноним  
Дата: 15.10.13 09:21
Оценка:
CEM>Сам я обычно стараюсь ничего стороннего не брать, потому что:

.NET библиотеки и компилятор свои или сторонние ?
Re[13]: своё vs. сторонее
От: IT Россия linq2db.com
Дата: 15.10.13 13:41
Оценка:
Здравствуйте, Doc, Вы писали:

IT>>Это уже проблема вызывающего класса. У обсуждаемого класса зависимостей нет вообще.

Doc>Дай угадаю, с классом выше ты поступишь так же? Или ты пишешь библиотеки, состоящие из одного класса?

Дай и я угадаю, в твоей луковице десятки классов выше. Ты пишешшь библиотеки, состоящие из одного класса на одну строчку функциональности?

Doc>Кстати, а что делать будешь, если нужны будут методы _service, в который нужно передать аргументы (которые скрыты внутри самого класса)?


Зависит. Ты же не думаешь, что в качестве параметра можно передавать только примитивные типы. Вообще-то ещё существуют делегаты, интерфейсы (да, да, интерфейсы можно использовать не только для сервисов!) и просто классы с методами, у которых вполне могут быть параметры.
Если нам не помогут, то мы тоже никого не пощадим.
Re[14]: своё vs. сторонее
От: Doc Россия http://andrey.moveax.ru
Дата: 15.10.13 16:46
Оценка:
Здравствуйте, IT, Вы писали:

IT>Дай и я угадаю, в твоей луковице десятки классов выше.


Не понял вопрос. Если про общее число классов, то да. Если про глубину вызовов, то нет.

IT>Ты пишешшь библиотеки, состоящие из одного класса на одну строчку функциональности?


Если надо по архитектуре приложения, то ничего страшного не вижу. Но только не "класс ради класса".

IT>Вообще-то ещё существуют делегаты, интерфейсы (да, да, интерфейсы можно использовать не только для сервисов!)


Ух ты, method injection ? Все же используешь DI? Но в примере ты все равно от зависимости не избавился. Да, перенес её в другой класс, но и там её надо как-то разруливать. Плюс, еще не известно кто должен знать про _service — исходный класс или вызывающий. Но это уже от логики приложения.
Re[8]: своё vs. сторонее
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 15.10.13 20:23
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, artelk, Вы писали:


A>>Этот проект, все же, несколько отличается от того, с чем приходится сталкиваться в энтерпрайзе.


IT>По поводу энтерпрайза. Как раз если и использовать DI для тестирования, то в таких проектах как linq1db. В энтерпрайзах 90% логики — это работа с базами данных. А в самых запущенных случаях вся логика вообще находится в сохранённых процедурах, т.е. в самой базе данных. И если у кого-нибудь хватит мозгов использовать DI, чтобы мокать такую логику, то что, скажите вы собираетесь тестировать, умение C# генерировать вызовы методов? Так это уже давно было сделано в MS.


IT>А те оставшиеся 10% нетривиальной логики, которую действительно нужно гонять на самых разных данных и желательно без БД, совершенно спокойно можно задизайнить таким образом, что всё, что ей нужно будет передаваться по необходимости. И всё. DI не нужен.


Вся логика в БД это крайне редкий случай. Сейчас средне умение писать SQL на столько низко, что мнгие не понимают что современные РСУБД это не только key-value storage.
Но даже если большая часть логики в БД, то обработка запроса выглядит так:


Result Method1(Parameters p)
{
    if(!CheckRequest(p))
    {
        return InvalidParametersResult(p);
    }

    if(!CheckUserRights(p))
    {
        return AccessDeniedResult(p);
    }

    if(CanUseCachedResult(p))
    {
        return CachedResult(p);
    }
    
    var dbResult = CallDatabase(p);

    if(!dbResult.IsValid)
    {
        return InvalidOperationResult(p, dbResult);
    }
    
    return Process(dbResult);
    
}



Нужно понимать что все методы, не примитивные, из одной строчки. Каждый их них потенциально может лезть в БД, использовать параметры и другие "сервисы" приложения. Тут DI начинает очень сильно помогать. Кроме того, для улучшения unit-тестирования самого Method1 можно часть вызываемых функций тоже подсовывать через DI. Другая часть функций может быть вынесена вне методов обработки запросов и внезапно такой AoP тоже реализуется через DI.

В итоге DI помогает собирать приложения по кусочкам, концентрируясь при этом на самих кусочках, а не на сборке.

Конечно бывает так, что разбить логику на несвязанные кусочки нельзя, тогда попытка применения DI выглядит жалко.
Re[4]: своё vs. сторонее
От: koodeer  
Дата: 15.10.13 21:02
Оценка:
Здравствуйте, IT, Вы писали:

IT>DI от лукавого. Мне тут в соседней ветке пытались объяснить что такого даёт DI, очень долго пытались, но так и не смогли.


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

Так вот, DI и прочие умные штуки дают следующее ценное свойство: они позволяют безбедно жить программистам, щедро впихнувшем в свои проекты именно эти фичи. Потому как мой некоторый личный опыт показывает следующее: те проекты, которые сделаны без этих умных фич, давно уже поддерживаются студентами/джуниорами, и первоначальным разработчикам ничего с них не перепадает. А вот те, где есть что-то эдакое, студенты не могут осилить, поэтому для внедрения каждой новой фичи обращаются к профессиональным разработчикам.
Re[15]: своё vs. сторонее
От: IT Россия linq2db.com
Дата: 16.10.13 00:30
Оценка: +1 -1
Здравствуйте, Doc, Вы писали:

IT>>Дай и я угадаю, в твоей луковице десятки классов выше.

Doc>Не понял вопрос. Если про общее число классов, то да. Если про глубину вызовов, то нет.

Ну а если нет, то в чём проблема?

IT>>Ты пишешшь библиотеки, состоящие из одного класса на одну строчку функциональности?

Doc>Если надо по архитектуре приложения, то ничего страшного не вижу. Но только не "класс ради класса".

Я могу тебе ответить тоже самое на твой вопрос.

IT>>Вообще-то ещё существуют делегаты, интерфейсы (да, да, интерфейсы можно использовать не только для сервисов!)


Doc>Ух ты, method injection ? Все же используешь DI?


Вот! То о чём я и говорю. Больные люди! Им везде мерещится DI.

Doc>Но в примере ты все равно от зависимости не избавился. Да, перенес её в другой класс, но и там её надо как-то разруливать.


И что? Я убрал нежелательную зависимость? Убрал. Да ещё так убрал, как DI и не снилось. А твой DI — это переливание из пустого в порожнее. Из одного места убираем, в другое добавляем, в треьем размазываем жидким слоем.
... << RSDN@Home 1.2.0 alpha 5 rev. 69>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: своё vs. сторонее
От: IT Россия linq2db.com
Дата: 16.10.13 00:40
Оценка: +3
Здравствуйте, koodeer, Вы писали:

K>Так вот, DI и прочие умные штуки дают следующее ценное свойство: они позволяют безбедно жить программистам, щедро впихнувшем в свои проекты именно эти фичи. Потому как мой некоторый личный опыт показывает следующее: те проекты, которые сделаны без этих умных фич, давно уже поддерживаются студентами/джуниорами, и первоначальным разработчикам ничего с них не перепадает. А вот те, где есть что-то эдакое, студенты не могут осилить, поэтому для внедрения каждой новой фичи обращаются к профессиональным разработчикам.


Это назвается job security. Манагерам и студентам надо понять одну простую вещь. Наличие в проекте DI — это очень чёткий признак over-design приложения. В 9 из 10 приложений DI нафиг не нужен, в том числе и для тестирования. Просто те, кто им начинает увлекаться уже по другому задизайнить приложение не в состоянии. Жалко их, людей с искалеченной DI судьбой.
... << RSDN@Home 1.2.0 alpha 5 rev. 69>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: своё vs. сторонее
От: IT Россия linq2db.com
Дата: 16.10.13 00:50
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>Нужно понимать что все методы, не примитивные, из одной строчки. Каждый их них потенциально может лезть в БД, использовать параметры и другие "сервисы" приложения. Тут DI начинает очень сильно помогать.


Если очень захотеть, то DI можно впихнуть куда угодно. Это не проблема. Только в твоём примере такой необходимости нет ни в одном месте. Валидация — это часть логики, какой-то тут DI? Юзер проверяется атрибутами, как правило доступен в контексте или обрабатвается более сложными способами вроде фильтрации данных SQL запросами, что фактически является частью безнес логики. Кеширование тоже лучше всего делается атрибутами, ну или простейшим хелпером на худой конец.

G>Кроме того, для улучшения unit-тестирования самого Method1 можно часть вызываемых функций тоже подсовывать через DI. Другая часть функций может быть вынесена вне методов обработки запросов и внезапно такой AoP тоже реализуется через DI.


Я же говорю, запихать можно куда угодно. Только надо ли?

G>В итоге DI помогает собирать приложения по кусочкам, концентрируясь при этом на самих кусочках, а не на сборке.


В собранном по кусочкам приложении невозможно разобраться. Зачастую, что бы понять его логику нужно запускать его под отладчиком. В общем, я уже устал это повторять. DI — это сломанная навигация по коду и логика, размазанная жидким поносом по всему приложению. Как правило от таких приложений смердит за версту и всякими другими архитектурными излишествами.
... << RSDN@Home 1.2.0 alpha 5 rev. 69>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: своё vs. сторонее
От: CEMb  
Дата: 16.10.13 02:33
Оценка:
Здравствуйте, scale_tone, Вы писали:

_>Как-то так.


Надо будет попробовать сделать проект по этой схеме правда команда у нас не большая, примерно один человек, иногда два
Re[16]: своё vs. сторонее
От: Doc Россия http://andrey.moveax.ru
Дата: 16.10.13 03:19
Оценка:
Здравствуйте, IT, Вы писали:

IT>Ну а если нет, то в чём проблема?


А проблем и нет.

Doc>>Ух ты, method injection ? Все же используешь DI?

IT>Вот! То о чём я и говорю. Больные люди! Им везде мерещится DI.

Просто сами шаблоны DI это не супер какая магия, а передача зависимостей. Их всего три — constructor injection, property injection и method injection. И та "магия", что творится в контейнере при создании экземпляра, к ним отношения не имеет.

Doc>>Но в примере ты все равно от зависимости не избавился. Да, перенес её в другой класс, но и там её надо как-то разруливать.


IT>И что? Я убрал нежелательную зависимость? Убрал. Да ещё так убрал, как DI и не снилось.


Ты перенес её в другой класс приложения. Вот тут как раз получается как ты и сказал "из одного места убираем, в другое добавляем, в треьем размазываем жидким слоем". С IoC не пришлось бы вызывающим классам знакомиться с _service.
Re[5]: своё vs. сторонее
От: Doc Россия http://andrey.moveax.ru
Дата: 16.10.13 03:20
Оценка:
Здравствуйте, koodeer, Вы писали:

K>Так вот, DI и прочие умные штуки дают следующее ценное свойство: они позволяют безбедно жить программистам, щедро впихнувшем в свои проекты именно эти фичи.


Учитесь тролить тоньше. А то очень толсто вышло
Re[17]: своё vs. сторонее
От: IT Россия linq2db.com
Дата: 16.10.13 03:30
Оценка: +3
Здравствуйте, Doc, Вы писали:

Doc>Ты перенес её в другой класс приложения.


Я её не переносил, она там, где и должна быть. Ты слишком однобоко понимаешь применение инструментов. DI — это не только ценный мех, цена которого, кстати, 0.5 по 10-ти бальной шкале. Это ещё и привнесённая в приложение сложность и эта сложность на порядок больше пользы.

Doc>Вот тут как раз получается как ты и сказал "из одного места убираем, в другое добавляем, в треьем размазываем жидким слоем".


Нет, жидким слоем, это не про зависимости, это про логику. Вот смотришь на такие погрызенные DI-ем методы и думашеь, что же они делают? За деревьями леса не видно. Одни, мля, какие-то левые сервисы дёргаются.

Doc>С IoC не пришлось бы вызывающим классам знакомиться с _service.


В случае с DI с ними вообще трудно познакомиться. Даже разработчику. Захочешь, хрен найдёшь.
... << RSDN@Home 1.2.0 alpha 5 rev. 69>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[18]: своё vs. сторонее
От: Doc Россия http://andrey.moveax.ru
Дата: 16.10.13 03:44
Оценка:
Здравствуйте, IT, Вы писали:

IT>Я её не переносил, она там, где и должна быть.


Лукавишь. Если изначально сервис должен был быть в вызывающих классах, то это был не пример "замены DI", а пример "исправления архитектуры".

Ты слишком однобоко понимаешь применение инструментов. DI — это не только ценный мех, цена которого, кстати, 0.5 по 10-ти бальной шкале. Это ещё и привнесённая в приложение сложность и эта сложность на порядок больше пользы.

IT>Нет, жидким слоем, это не про зависимости, это про логику. Вот смотришь на такие погрызенные DI-ем методы и думашеь, что же они делают? За деревьями леса не видно. Одни, мля, какие-то левые сервисы дёргаются.


Я так понимаю, это про то, что по F12 в сорцы не перейти (без всяких плагинов для VS)? При изучении кода конкретного метода то, что делает вызов (что должен делать) должно быть ясно из его названия и/или комментария и окружающего кода. А то, что реализующий это класс делает это корректно — из unit test-ов. Ты же не перечитываешь код System.String при каждой операции со строкой?

Хотя если методы сервиса называется DoAction1() итп то такой разработчик сам себе злобный буратино.
Re[12]: своё vs. сторонее
От: UberPsychoSvin  
Дата: 16.10.13 04:32
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Dziman, Вы писали:


D>>Можно пример проблемы именно из-за DI?


IT>Я уже устал об этом говорить. DI ломает навигацию по проекту, что существенно затрудняет читабельность и понимабильность кода приложения. Бизнес логика разбивается на части и разносится по разным частям приложения. Это затрудняет модификацию приложения.


IT>А всегда ли это нужно?

Если DI нужно только для тестов, в С# например можно в качестве интерфейса использовать сами классы. Если нужно их мокнуть, то соответствующие методы делаются виртуальными.
Re[6]: своё vs. сторонее
От: Yoriсk  
Дата: 16.10.13 08:39
Оценка:
Здравствуйте, IT, Вы писали:

IT>
IT>void MyVeryPrimitiveMethod()
IT>{
IT>    var value1 = _service1.GetValue1();
IT>    var value2 = _service2.GetValue2();

IT>    var result = value1 * value2;

IT>    _service3.SetResult(result);
IT>}
IT>

IT>И это всё вместо:
IT>Как по-твоему где больше зависимостей?

Одинаково. Ваш код в полном виде выглядит как-то так:
{
///// far far away
var value1 = _service1.GetValue1();
var value2 = _service2.GetValue2();
var result = MyVeryPrimitiveMethod(value1 * value2);
_service3.SetResult(result);
////
}

int MyVeryPrimitiveMethod(int value1, int value2)
{
    return value1 * value2;
}




Хотя как по мне, что
_serviceInterfaceFromDI.GetValue1();

что
_concreteClass.GetValue1();

тоже в 99.9% случаях дают одинаковую зависимость, потому что в этих 99.9% в данном месте всегда будет одна и та же и совершенно конкретная имплементация.
Всё тлен, всё тщета.
Re[10]: своё vs. сторонее
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 16.10.13 09:28
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, gandjustas, Вы писали:


G>>Нужно понимать что все методы, не примитивные, из одной строчки. Каждый их них потенциально может лезть в БД, использовать параметры и другие "сервисы" приложения. Тут DI начинает очень сильно помогать.


IT>Если очень захотеть, то DI можно впихнуть куда угодно. Это не проблема.


Необходимости в DI вообще никогда нет. Любой код может быть написан без DI. Но альтернатива в виде ball-of-mud архитектуры зачастую хуже, чем DI на каждый чих. Можно конечно писать слабосвязный код и без DI, но там мало кто умеет.

IT>Только в твоём примере такой необходимости нет ни в одном месте. Валидация — это часть логики, какой-то тут DI? Юзер проверяется атрибутами, как правило доступен в контексте или обрабатвается более сложными способами вроде фильтрации данных SQL запросами, что фактически является частью безнес логики.

Я же писал что весь AoP из атрибутов чаще всего реализуется средствами DI. Так что странно что ты предлагаешь использовать то, что сам в предыдущем предложении отвергаешь.

IT>Кеширование тоже лучше всего делается атрибутами, ну или простейшим хелпером на худой конец.

Ну вот хелпер у тебя зависит от ASP.NET, а метод — не зависит. Но если у тебя нет DI, то unit-тестами сложно будет покрыть метод.


G>>Кроме того, для улучшения unit-тестирования самого Method1 можно часть вызываемых функций тоже подсовывать через DI. Другая часть функций может быть вынесена вне методов обработки запросов и внезапно такой AoP тоже реализуется через DI.

IT>Я же говорю, запихать можно куда угодно. Только надо ли?
Я видел фрейморки, которые использовали эти сам атрибуты без DI, это был ад. Так что я в этом случае за DI.

G>>В итоге DI помогает собирать приложения по кусочкам, концентрируясь при этом на самих кусочках, а не на сборке.

IT>В собранном по кусочкам приложении невозможно разобраться. Зачастую, что бы понять его логику нужно запускать его под отладчиком. В общем, я уже устал это повторять. DI — это сломанная навигация по коду и логика, размазанная жидким поносом по всему приложению.
Если у тебя есть решарпер, то не проблема. Я уже и без решарпера научился разбирать сильно DI код.


IT>Как правило от таких приложений смердит за версту и всякими другими архитектурными излишествами.

Я такого и без DI видел много раз.
Re[19]: своё vs. сторонее
От: IT Россия linq2db.com
Дата: 16.10.13 14:54
Оценка:
Здравствуйте, Doc, Вы писали:

IT>>Я её не переносил, она там, где и должна быть.

Doc>Лукавишь. Если изначально сервис должен был быть в вызывающих классах, то это был не пример "замены DI", а пример "исправления архитектуры".

Я же говорю, люди с искалеченной DI-ем судьбой, по другому думать уже не могут. Кто тебе вообще сказал, что сервис должен быть изначально?

Doc>Я так понимаю, это про то, что по F12 в сорцы не перейти (без всяких плагинов для VS)? При изучении кода конкретного метода то, что делает вызов (что должен делать) должно быть ясно из его названия и/или комментария и окружающего кода. А то, что реализующий это класс делает это корректно — из unit test-ов. Ты же не перечитываешь код System.String при каждой операции со строкой?


Не надо путать божий дар с яичницей. Или тебе ообъяснить разницу между System.String и GetcustomerByID? Какие требования предъявляются при разработке к одному методу, а какие к другому.

Doc>Хотя если методы сервиса называется DoAction1() итп то такой разработчик сам себе злобный буратино.


Считать себя умнее других также плохо как и считать других глупее себя. Так что давай обойдёмся без абстрактных индусов.
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: своё vs. сторонее
От: IT Россия linq2db.com
Дата: 16.10.13 15:06
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

IT>>Если очень захотеть, то DI можно впихнуть куда угодно. Это не проблема.

G>Необходимости в DI вообще никогда нет. Любой код может быть написан без DI. Но альтернатива в виде ball-of-mud архитектуры зачастую хуже, чем DI на каждый чих. Можно конечно писать слабосвязный код и без DI, но там мало кто умеет.

А кто сказал, что DI — это слабосвязный код? DI устраняет только один тип зависимости — зависимость от реализаций, но при этом добавляет новые сущности в систему и добавляет кучу зависимостей между системой и этими сущностями. И не известно ещё что хуже с точки зрения той же теории систем, которая утверждает, что общая сложность системы зависит прежде всего от количества связей между частями системы. В случае с DI у нас и частей стало больше и зависимостей между ними.

G>Если у тебя есть решарпер, то не проблема. Я уже и без решарпера научился разбирать сильно DI код.


Это не более чем умение ходить на ходулях по граблям. Зачем мне это, если без этого можно обойтись?

IT>>Как правило от таких приложений смердит за версту и всякими другими архитектурными излишествами.

G>Я такого и без DI видел много раз.

Зато такого как с DI я не видел нигде.
Если нам не помогут, то мы тоже никого не пощадим.
Re[20]: своё vs. сторонее
От: Doc Россия http://andrey.moveax.ru
Дата: 16.10.13 15:35
Оценка:
Здравствуйте, IT, Вы писали:

IT>Кто тебе вообще сказал, что сервис должен быть изначально?


Ага, т.е. сервис в том примере вообще лишний? Если так — то это тем более пример исправления кривой архитектуры, а не изгнания IoC

IT>Не надо путать божий дар с яичницей. Или тебе ообъяснить разницу между System.String и GetcustomerByID?


Если GetcustomerByID проходит unit test — мне без разницы что внутри, до того момента, как будут основания это проверить.

IT>Считать себя умнее других также плохо как и считать других глупее себя. Так что давай обойдёмся без абстрактных индусов.


Во, начни с себя и завязывай раздавать диагнозы
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.