ревью должно проходить не однажды после написания «дремучего модуля», а на промежуточных стадиях.
В этом случае ситуация с неиспользуемым кодом скорее всего всплывет.
А в случае с хорошим дизайном — «ненужным» может остаться только целый класс, который какую-то функциональность да выполняет, и который может потребоваться для своих целей в будущем. По крайней мере полного удаления он в данном случае не заслуживает
А в чем «технические» причины запрета-то?
Причины запрета есть, согласен. Причина запрета — это не «эппл боится потерять рынок». От этого запрета конечным пользователям только лучше. Я согласен со всем этим.
Но автор оригинального поста лишь говорил о том, что эти причины — нетехнического плана. Технический — на мой взгляд — это «архитектура не позволяет». Или даже «оперативки не хватает». Но как я понял из статьи (у меня нет айфона), озу на запуск в однозадачном режиме даже на предыдущих моделях таки хватило бы.
Маркетинговые причины — вижу. Решение эппл — правильное. И пользователям, и самой компании, да и разработчикам под айфон в конечном счете от этого только лучше.
Ставим плюс — если хотим, чтобы такие статьи появлялись на хабре.
Я не хочу, чтобы статьи, вроде этой появлялись на хабре.
Но это не значит, что я не согласен с ней. Наоборот, согласен. Так согласно логике поста, что я должен поставить? :) Минус или плюс?
Работа с медицинскими приборами. Конкретно на данный момент — импорт данных из них.
На выходе данные в строго определенном формате, а на входе — множество приборов, которые внутри содержат, в общем и целом, одни и те же данные, но либо в разных форматах, либо запрашивать их приходится разными способами.
В итоге имеем несколько интерфейсов «коммуникационного» уровня, для импорта различных типов данных из разных устройств, интерфейсы для конвертации в идентичный низкоуровневый «промежуточный» формат данных для групп приборов, и конвертация в итоговый выходной формат. Это если «грубо».
Чем выше уровнем, тем число реализаций каждого интерфейса, конечно, уменьшается. Но и даже там, где сейчас всего одна реализация интерфейса, при добавлении поддержки доп. прибора легко появится еще одна, поэтому приходится предусматривать.
Мы чуть выше дискутировали по этому вопросу. У вас же не пробрасывается context в глубину классов?
В этом пункте в посте я описывал нежелательную реализацию, когда в конструкторе класса (ну или в виде @Inject Context context;) есть зависимость от IUnityContainer'a с целью .Resolve объектов внутри класса.
>Вообще создавать интерфейс на каждый класс это бред.
Это очень зависит от конкретной задачи. Конечно, если класс простой с единственной ответственностью и исключено создание другой реализации этой же ответственности — то это бред.
А в некоторых случаях практически каждая операция легко сводится к интерфейсу, а для разных входных объектов выполнять эти операции надо по-разному. Вот у меня в текущем проекте и получается, что в 90% случаев класс реализует интерфейс. И на каждый интерфейс по 2 класса минимум.
Ну мы и пришли к тому же: что лучше контейнер использовать на начальном этапе, а в глубине использовать конкретные интерфейсы. Интерфейсы фабрик в частности.
ага, правильно
Тогда получается, что этот самый container таки должен пробрасываться до всех мест, где требуется инстанцировать новые объекты. Или я не прав?
Ну то есть на мой взгляд аналогия с юнити полная: хочешь инстанциировать через контейнер — пробрасывай контейнер.
А в топике я и акцентировал, что пробрасывание контейнера — не самая лучшая идея.
ну и по поводу @Inject-a проперти, я чуть ниже писал… что это, конечно, на вкус и цвет, но мне указание интерфейсов в конструкторе больше импонирует:
Но даже при xml-конфигурировании библиотеки, в которых реализуются интерфейсы, должны быть статически слинкованы с исходной библиотекой (которая использует RoboContainer)?
Или контейнер умеет динамически подгружать зависимости?
Оно может, конечно. И синтаксис для этого есть в Юнити…
Но я потому и написал, что это «совсем замечательно», когда через конструктор. Это да, личное мнение. На мой взгляд, в большинстве случаев инициализации зависимостей через проперти стоит избегать. Причина — та же самая, непонятно, когда это проперти инициализировать необходимо, а когда — нет.
создавая объекты через .Resolve мы разрешаем зависимости дочерних классов. То есть дочерние классы у нас как раз inversion of control очень даже соблюдают по определению.
Класс, из которого .Resolve вызывается — он тоже может быть очень даже IoC, а Юнити он использует внутри себя для удобного создания дочерних классов и разрешения их зависимостей.
В данном случае это как бы «корень» приложения в терминологии Prism — точка, в которой становятся известны объекты, которые будут реализовывать интерфейсы.
Я вот столкнулся буквально недавно с ситуацией, в которой на мой взгляд использование контейнера более чем оправдано — как раз за счет сложных взаимозависимостей.
Объекты с одним общим интерфейсом в зависимости от текущий условий(объектов на входе) требовали очень разных параметров в конструкторе.
Поэтому мне показалось логичным заставить эти входные объекты регистрировать нужные интерфейсы, а в самой библиотеке резолвить интерфейсы через Unity.
Спутанно объяснил, наверное :) Но проблема как раз в том, что объем кода значительный, и к простому примеру сложно свести…
Я извиняюсь, но как можно ни разу явно не использовать Resolve в рамках не WPF проекта?
В рамках Prism'a я это себе представляю, но в контексте невизуальных библиотек — не очень. Поясните, пожалуйста.
Проблема может быть в том, что на этой группе в 50-100 человек и держится трекер. Не 50-100 на самом деле, а больше, конечно, но факт, что это 1-2% от посетителей рутрекера. Это те, кто релизят. И если стимулом к релизам у них была та самая пузомерка и уважение в глазах других за релизы, то как минимум 50% мотивации они лишились.
Если с новым рейтингом эти релизеры не потеряются для трекера — тогда да, проблемы никакой не будет. Мне же, как нечастому пользователю, по большому счету все равно.
В этом случае ситуация с неиспользуемым кодом скорее всего всплывет.
А в случае с хорошим дизайном — «ненужным» может остаться только целый класс, который какую-то функциональность да выполняет, и который может потребоваться для своих целей в будущем. По крайней мере полного удаления он в данном случае не заслуживает
Это касается только организаций/оптовых закупок, или если я на ибее телефон купил, мне тоже теперь с таможней общаться?
Причины запрета есть, согласен. Причина запрета — это не «эппл боится потерять рынок». От этого запрета конечным пользователям только лучше. Я согласен со всем этим.
Но автор оригинального поста лишь говорил о том, что эти причины — нетехнического плана. Технический — на мой взгляд — это «архитектура не позволяет». Или даже «оперативки не хватает». Но как я понял из статьи (у меня нет айфона), озу на запуск в однозадачном режиме даже на предыдущих моделях таки хватило бы.
Маркетинговые причины — вижу. Решение эппл — правильное. И пользователям, и самой компании, да и разработчикам под айфон в конечном счете от этого только лучше.
Но технические-то причины где?
Я не хочу, чтобы статьи, вроде этой появлялись на хабре.
Но это не значит, что я не согласен с ней. Наоборот, согласен. Так согласно логике поста, что я должен поставить? :) Минус или плюс?
На выходе данные в строго определенном формате, а на входе — множество приборов, которые внутри содержат, в общем и целом, одни и те же данные, но либо в разных форматах, либо запрашивать их приходится разными способами.
В итоге имеем несколько интерфейсов «коммуникационного» уровня, для импорта различных типов данных из разных устройств, интерфейсы для конвертации в идентичный низкоуровневый «промежуточный» формат данных для групп приборов, и конвертация в итоговый выходной формат. Это если «грубо».
Чем выше уровнем, тем число реализаций каждого интерфейса, конечно, уменьшается. Но и даже там, где сейчас всего одна реализация интерфейса, при добавлении поддержки доп. прибора легко появится еще одна, поэтому приходится предусматривать.
Мы чуть выше дискутировали по этому вопросу. У вас же не пробрасывается context в глубину классов?
В этом пункте в посте я описывал нежелательную реализацию, когда в конструкторе класса (ну или в виде @Inject Context context;) есть зависимость от IUnityContainer'a с целью .Resolve объектов внутри класса.
>Вообще создавать интерфейс на каждый класс это бред.
Это очень зависит от конкретной задачи. Конечно, если класс простой с единственной ответственностью и исключено создание другой реализации этой же ответственности — то это бред.
А в некоторых случаях практически каждая операция легко сводится к интерфейсу, а для разных входных объектов выполнять эти операции надо по-разному. Вот у меня в текущем проекте и получается, что в 90% случаев класс реализует интерфейс. И на каждый интерфейс по 2 класса минимум.
Но с другой — container.Resolve разве не предоставляет нам возможность прямого поиска зависимостей?
Другой вопрос, что такое использование юнити (как ServiceLocator'а) в большинстве случаев не оправдано — это да.
«То есть код вида:
class TextManager {
public TextManager(ITextReader reader, ITextWriter writer) {
}
}
это хорошо»
А участок с пробросом контейнера идет под подзаголовком «А когда — не очень» как пример не самого лучшего приема
Надеюсь, мы друг друга поняли :)
Тогда получается, что этот самый container таки должен пробрасываться до всех мест, где требуется инстанцировать новые объекты. Или я не прав?
Ну то есть на мой взгляд аналогия с юнити полная: хочешь инстанциировать через контейнер — пробрасывай контейнер.
А в топике я и акцентировал, что пробрасывание контейнера — не самая лучшая идея.
ну и по поводу @Inject-a проперти, я чуть ниже писал… что это, конечно, на вкус и цвет, но мне указание интерфейсов в конструкторе больше импонирует:
ILogger _logger;
// конструктор
public Sample(ILogger logger, IConnection connection, IFacade facade) {
_logger = logger;…
}
Или контейнер умеет динамически подгружать зависимости?
А как происходит инстанциирование класса Sample в первом случае?
Но я потому и написал, что это «совсем замечательно», когда через конструктор. Это да, личное мнение. На мой взгляд, в большинстве случаев инициализации зависимостей через проперти стоит избегать. Причина — та же самая, непонятно, когда это проперти инициализировать необходимо, а когда — нет.
Класс, из которого .Resolve вызывается — он тоже может быть очень даже IoC, а Юнити он использует внутри себя для удобного создания дочерних классов и разрешения их зависимостей.
В данном случае это как бы «корень» приложения в терминологии Prism — точка, в которой становятся известны объекты, которые будут реализовывать интерфейсы.
Объекты с одним общим интерфейсом в зависимости от текущий условий(объектов на входе) требовали очень разных параметров в конструкторе.
Поэтому мне показалось логичным заставить эти входные объекты регистрировать нужные интерфейсы, а в самой библиотеке резолвить интерфейсы через Unity.
Спутанно объяснил, наверное :) Но проблема как раз в том, что объем кода значительный, и к простому примеру сложно свести…
В рамках Prism'a я это себе представляю, но в контексте невизуальных библиотек — не очень. Поясните, пожалуйста.
Если с новым рейтингом эти релизеры не потеряются для трекера — тогда да, проблемы никакой не будет. Мне же, как нечастому пользователю, по большому счету все равно.
А вот нигде помимо него, видимо, и не освещалось. Ну и я сам виноват, конечно, что проспал событие.