Когда использовать Внедрение зависимости

Базовая структура Вашего игрового механизма использует Шаблон состояния . Объекты Вашего игрового поля одиночные элементы из различных классов. Структура каждого состояния может использовать Стратегическая модель или Шаблонный Метод .

А Фабрика используется для создания плееров, которые введены в список плееров, другого одиночного элемента. GUI будет наблюдать на Игровом Механизме при помощи Шаблон "наблюдатель" и взаимодействовать с этим при помощи одного из нескольких Объектов команды, созданных с помощью Шаблон "команда" . Использование Наблюдателя и Команда могут использоваться с в контексте Пассивное Представление , Но примерно любой шаблон MVP/MVC мог использоваться в зависимости от Ваших предпочтений. При сохранении игры, необходимо захватить сувенир из, его - текущее состояние

я рекомендующий просматривающий некоторые шаблоны на этом сайт , и посмотрите, захватывает ли какой-либо из них Вас как начальную точку. Снова основа Вашей игровой доски будет конечным автоматом. Большинство игр будет представленный двумя состояниями pre-game/setup и фактической игрой. Но Вы можете, имел больше состояний, если игра, которую Вы моделируете, имеет несколько отличных режимов игры. Состояния не должны быть последовательными, например, wargame Ось & Сражения имеют плату сражения, которую игроки могут использовать для разрешения сражений. Таким образом, существует три предварительных игры состояний, системная плата, плата сражения с игрой, постоянно переключающейся между платой сражения и системной платой. Конечно, последовательность поворота может также быть представлена конечным автоматом.

48
задан CodeMonkey 16 October 2009 в 21:53
поделиться

6 ответов

Два слова, модульное тестирование .

Одной из наиболее веских причин для DI является упрощение модульного тестирования без необходимости обращаться к базе данных и беспокоиться о настройке «тестовые» данные.

50
ответ дан 26 November 2019 в 18:51
поделиться

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

Вот пример ...

У вас есть база данных.

У вас есть код, который обращается к базе данных и возвращает объекты

У вас есть объекты бизнес-домена, которые принимают объекты предыдущего элемента и выполняют некоторую логику с их.

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

Абстрагирование Такие сторонние компоненты и фреймворки также могут вам помочь.

Помимо примера тестирования, есть несколько мест, где DI можно использовать с помощью подхода «Дизайн по контракту». Возможно, вы сочтете целесообразным создать своего рода механизм обработки, который вызывает методы объектов, которые вы в него вводите. Хотя он может и не «обрабатывать его», он запускает методы, которые имеют разную реализацию в каждом предоставляемом вами объекте.

Я видел пример этого, где каждый объект бизнес-области имел функцию «Сохранить», которая вызывалась после того, как он был введен в процессор. Процессор изменил компонент, добавив информацию о конфигурации, и команда Save обработала первичное состояние объекта. По сути, DI дополнил реализацию полиморфного метода объектов, соответствующих интерфейсу.

Есть несколько мест, где DI можно использовать в рамках подхода «Дизайн по контракту». Возможно, вы сочтете целесообразным создать своего рода механизм обработки, который вызывает методы объектов, которые вы в него вводите. Хотя он может не «обрабатывать» его по-настоящему, он запускает методы, которые имеют разную реализацию в каждом предоставляемом вами объекте.

Я видел пример этого, где каждый объект бизнес-области имел функцию «Сохранить», которая вызывалась после того, как он был введен в процессор. Процессор изменил компонент, добавив информацию о конфигурации, и команда Save обработала первичное состояние объекта. По сути, DI дополнил реализацию полиморфного метода объектов, соответствующих интерфейсу.

Есть несколько мест, где DI можно использовать в рамках подхода «Дизайн по контракту». Возможно, вы сочтете целесообразным создать своего рода механизм обработки, который вызывает методы объектов, которые вы в него вводите. Хотя он может не «обрабатывать» его по-настоящему, он запускает методы, которые имеют разную реализацию в каждом предоставляемом вами объекте.

Я видел пример этого, где каждый объект бизнес-домена имел функцию «Сохранить», которая вызывалась после того, как он был введен в процессор. Процессор изменил компонент, добавив информацию о конфигурации, и команда Save обработала первичное состояние объекта. По сути, DI дополнил реализацию полиморфного метода объектов, соответствующих интерфейсу.

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

Я видел пример этого, где каждый объект бизнес-домена имел функцию «Сохранить», которая вызывалась после того, как он был введен в процессор. Процессор изменил компонент, добавив информацию о конфигурации, и Save обработал первичное состояние объекта. По сути, DI дополнил реализацию полиморфного метода объектов, соответствующих интерфейсу.

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

Я видел пример этого, где каждый объект бизнес-области имел функцию «Сохранить», которая вызывалась после того, как он был введен в процессор. Процессор изменил компонент, добавив информацию о конфигурации, и команда Save обработала первичное состояние объекта. По сути, DI дополнил реализацию полиморфного метода объектов, соответствующих интерфейсу.

Я видел пример этого, где каждый объект бизнес-области имел функцию «Сохранить», которая вызывалась после того, как он был введен в процессор. Процессор изменил компонент, добавив информацию о конфигурации, и команда Save обработала первичное состояние объекта. По сути, DI дополнил реализацию полиморфного метода объектов, соответствующих интерфейсу.

Я видел пример этого, где каждый объект бизнес-домена имел функцию «Сохранить», которая вызывалась после того, как он был введен в процессор. Процессор изменил компонент, добавив информацию о конфигурации, и команда Save обработала первичное состояние объекта. По сути, DI дополнил реализацию полиморфного метода объектов, соответствующих интерфейсу.

5
ответ дан 26 November 2019 в 18:51
поделиться

Даже если вы не измените структуру своей программы на этапах разработки, вы обнаружите, что вам необходимо получить доступ к нескольким подсистемам из разных частей вашей программы. С DI каждый из ваших классов просто должен запрашивать услуги, и вам не нужно выполнять все подключения вручную.

Это действительно помогает мне сосредоточиться на взаимодействии вещей в разработке программного обеспечения, а не на том, «кому нужно носить что-то с собой, потому что это понадобится кому-то позже ».

Кроме того, он просто экономит ОЧЕНЬ много работы по написанию шаблонного кода. Мне нужен синглтон? Я просто настраиваю класс как один. Можно ли с таким "синглтоном" потестить? Да, я все еще могу (поскольку я только что НАСТРОИЛ его, чтобы он существовал только один раз, но тест может создать альтернативную реализацию).

Но, Между прочим, с текущим приложением я НЕ тестирую модули (плохо, плохо), но я ВСЕ ЕЩЕ не мог жить с DI. Гораздо проще перемещать предметы и сохранять классы небольшими и простыми.

7
ответ дан 26 November 2019 в 18:51
поделиться

Внедрение зависимостей дает вам возможность тестировать отдельные блоки кода изолированно.

Допустим, у меня есть класс Foo , например, который принимает в своем конструкторе экземпляр класса Bar . Один из методов на Foo может проверить, что значение свойства Bar является тем, которое позволяет выполнять другую обработку Bar .

public class Foo
{
    private Bar _bar;

    public Foo(Bar bar)
    {
        _bar = bar;
    }

    public bool IsPropertyOfBarValid()
    {
        return _bar.SomeProperty == PropertyEnum.ValidProperty;
    }
}

Теперь давайте скажем, что Bar создается, и его свойства устанавливаются на данные из некоторого источника данных в его конструкторе. Как я могу протестировать метод IsPropertyOfBarValid () из Foo (игнорируя тот факт, что это невероятно простой пример)? Хорошо, Foo зависит от экземпляра Bar , переданного в конструктор, который, в свою очередь, зависит от данных из источника данных, для которого установлены его свойства. Что мы хотели бы сделать, так это иметь какой-то способ изолировать Foo от ресурсов, от которых он зависит, чтобы мы могли тестировать его изолированно.

Вот где вступает в силу внедрение зависимостей. Мы хотим иметь некоторый способ подделки экземпляра Bar , переданного в Foo , чтобы мы могли управлять свойствами, установленными на этом поддельном Bar , и достичь того, что мы намеревались сделать, проверьте, что реализация IsPropertyOfBarValid () делает то, что мы ожидаем, т.е. возвращает истину, когда Bar.SomeProperty == PropertyEnum.ValidProperty , и ложь для любого другого значения.

Есть два типа фальшивых объектов: Mocks и Stubs. Заглушки предоставляют входные данные для тестируемого приложения, так что тест можно выполнить на чем-то еще. Моки, с другой стороны, обеспечивают входные данные для теста, чтобы решить, прошел ли тест или нет.

У Мартина Фаулера есть отличная статья о разнице между макетами и заглушками

4
ответ дан 26 November 2019 в 18:51
поделиться

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

1
ответ дан 26 November 2019 в 18:51
поделиться

Лично я бы написал get_user_group () , а не get_group_for_user () , так как он чувствует себя как правило, читает лучше для меня. Конечно, я использую язык программирования, в котором допускаются апострофы в именах:

proc get_user's_group {id} {#...}

Хотя некоторые из более плодовитых неанглийских европейских пользователей используют его в качестве сепаратора слова:

proc user'group {id} {#...}

друг к другу.

-121--3770432-

Я думаю, что DI стоит использовать, когда у вас есть много услуг / компонентов, реализации которых должны быть выбраны во время выполнения на основе внешней конфигурации. (Обратите внимание, что такая конфигурация может принимать форму XML-файла или комбинации аннотаций кода и отдельных классов; выберите то, что удобнее.)

В противном случае я бы просто использовал сервивелок, который намного «зажигал» и проще понять, чем целый DI Framework.

Для тестирования подразделения я предпочитаю использовать Mocking API, который может использовать объекты по требованию, вместо того, чтобы они были «введены» в тестированный блок из теста. Для Java одна такая библиотека моя, Jmockit .

2
ответ дан 26 November 2019 в 18:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: