Я видел два отличных видеороликов (this и this) о введении зависимостей, законе о демерете и глобальных состояниях (синглтоны считаются глобальными).C++ Инъекция зависимостей + Закон Деметры + регистратор/утверждение
Я думаю, что у меня есть основная идея, но у меня уже есть некоторые одноэлементные классы в моей библиотеке. Однако, если мне нужен тестовый и «хорошо продуманный» или «менее связанный» код, я должен использовать DI и LoD. Это, конечно, означает, что синглтоны (как шаблон дизайна) являются злыми, потому что вызывающий не выполняет сейчас, а любая зависимость от глобальной вещи плоха, по крайней мере, с точки зрения тестирования.
Более конкретно, я строю простой игровой движок, не используя более крупные сторонние библиотеки. Это означает, что я должен работать с кодом платформы и с низким уровнем кода.
Давайте будем более конкретными. У меня есть раздел Math в моей библиотеке, где у меня есть класс Vector2. Он должен иметь возможность «throw assert», когда неверные данные вводятся для одной из его функций. Или должен быть способен зарегистрировать его как ошибку. Или оба. До этого времени я просто использовал Singleton<Logger>
, поэтому я смог получить к нему доступ повсюду.
Но я согласен, что эти вещи не должны использоваться, и DI решает эти проблемы. Например. что, если регистратор еще не инициализирован? Что делать, если я хочу фиктивный логгер для тестов? И так далее ... Что вы рекомендуете для этих случаев (например, классы Logger и Assert)?
Также LoD говорит, что я не должен использовать аксессоры для объектов (например, getObjectA()->getObjectB()->doSomething()
). Вместо этого передайте их как параметр функции/constructor. Все в порядке, что все проще тестировать (и отлаживать), но может быть больно пропустить эти функции.
Рассмотрим пример двигателя Unity. У GameObject есть метод для получения компонента из этого объекта. Например. если я хочу, чтобы вручную преобразовать свой объект у меня нет выбора для вызова «объект добытчика», что-то вроде этого:
this.GetComponent<Transform>().SetPosition(...);
Это против Лода, не так ли?
Спасибо, я уже закончил создание класса коллекций, о котором вы упомянули выше. Также я не был достаточно конкретным, конечно, я не использую код платформы низкого уровня напрямую, но вместо этого использую абстрактные классы/интерфейсы. – csisy