Вы можете использовать метакласс, который переопределяет метод __str__
базового класса объекта класса, type
:
class meta(type):
def __str__(cls):
return cls.__name__
class A(metaclass=meta):
pass
print(str(A))
Это выводит:
A
Думайте о своем дизайне. DI позволяет Вам изменяться, как Ваш код функционирует через изменения конфигурации. Это также позволяет Вам повреждать зависимости между классами так, чтобы можно было изолировать и протестировать легче объекты. Необходимо определить, где это имеет смысл и где он не делает. Нет никакого стандартного ответа.
А хорошее эмпирическое правило - это, если ее слишком твердое для тестирования у Вас есть некоторые проблемы с единственной ответственностью и статическими зависимостями. Изолированный код, который выполняет единственную функцию в класс и повреждает ту статическую зависимость путем извлечения интерфейса и использования платформы DI для введения корректного экземпляра во времени выполнения. Путем выполнения этого Вы делаете его тривиальным для тестирования этих двух частей отдельно.
Основная проблема с внедрением зависимости состоит в том, что, в то время как оно дает появление слабо связанной архитектуры, оно действительно не делает.
то, Что Вы действительно делаете, перемещает ту связь со времени компиляции ко времени выполнения, но все еще если классу A нужен некоторый интерфейс B для работы, экземпляр класса, который реализует потребности интерфейса B все еще, чтобы быть обеспеченным.
Внедрение зависимости должно только использоваться для частей приложения, которое должно быть изменено динамично, не перекомпилировав основной код.
Использование, которое я видел полезный для Инверсии шаблона Управления:
Внедрение зависимости должно только использоваться для частей приложения, которое должно быть изменено динамично, не перекомпилировав основной код
, DI должен использоваться для изоляции кода от внешних ресурсов (базы данных, веб-сервисы, xml файлы, сменная архитектура). Количество времени, которое это заняло бы для тестирования логики в коде, будет почти препятствовать в большом количестве компаний при тестировании компонентов, которые ЗАВИСЯТ от базы данных.
В большинстве приложений база данных не собирается изменяться динамично (хотя она могла), но вообще говоря, это - почти всегда хорошая практика для НЕ привязки приложения с конкретным внешним ресурсом. Сумма вовлекает в изменяющиеся ресурсы, должно быть низким (классы доступа к данным должны редко иметь цикломатическую сложность выше одной в, он - методы).
Что Вы подразумеваете "под просто добавлением свойства к классу?"
Мое эмпирическое правило должно сделать единицу класса тестируемой. Если Ваш класс полагается на детали реализации другого класса, который должен быть осуществлен рефакторинг/абстрагирован до такой степени, что классы могут быть протестированы в изоляции.
РЕДАКТИРОВАНИЕ: Вы упоминаете полную лодку интерфейсов в конструкторе. Я советовал бы использовать методы set/методов get вместо этого. Я нахожу, что это делает вещи намного легче поддержать в конечном счете.
Я делаю это только, когда это помогает с разделением проблем.
Как, возможно, перекрестный проект я предоставил бы интерфейс лицам, осуществляющим внедрение в одном из моего проекта библиотеки, и проект реализации введет любую определенную реализацию, в которой они хотят.
, Но это - об этом... все другие случаи, это просто сделало бы систему излишне сложной
Даже со всеми фактами и процессами в мире.. каждое решение сводится к личному выбору - Забыл, где я считал, что
думаю, что это - больше опыта / вызов времени полета. В основном, если Вы рассматриваете зависимость как объект кандидата, который может быть заменен в ближайшем будущем, использовать внедрение зависимости. Если я буду видеть 'classA и его зависимости' как один блок для замены, то я, вероятно, не буду использовать DI для A deps.
Самое большое преимущество - то, что это поможет Вам понять или даже раскрыть архитектуру своего приложения. Вы будете в состоянии видеть очень ясно, как Ваши цепочки зависимости работают и в состоянии внести изменения в отдельные части, не требуя, чтобы Вы изменили вещи, которые не связаны. Вы закончите со слабо связанным приложением. Это продвинет Вас в лучший дизайн, и Вы будете удивлены, когда можно будет продолжать делать улучшения, потому что дизайн поможет Вам продолжать разделять и организовывать код продвижение. Это может также упростить поблочное тестирование, потому что у Вас теперь есть естественный способ заменить реализациями конкретных интерфейсов.
существуют некоторые приложения, которые являются просто холостыми, но если бы существует сомнение, я шел бы вперед и создал бы интерфейсы. После некоторой практики это не большая часть нагрузки.
Другой объект, с которым я борюсь, , где я должен использовать внедрение зависимости? , Где Вы берете свою зависимость от StructureMap? Только в приложении запуска? Это означает, что все реализации должны быть вручены полностью вниз от верхнего слоя до самого нижнего слоя?
Я использую замок Windsor/Microkernel, у меня нет опыта ни с чем больше, но мне нравится он много.
Что касается того, как Вы решаете, что ввести? До сих пор следующее эмпирическое правило служило мне хорошо: Если класс так прост, что ему не нужны модульные тесты, можно не стесняться инстанцировать его в классе, иначе Вы, вероятно, хотите иметь зависимость через конструктора.
Что касается того, необходимо ли создать интерфейс по сравнению только с созданием методов и свойств, виртуальных, я думаю, что необходимо пойти интерфейсным путем также, если Вы любой a) видит, что класс имеет некоторый уровень возможности многократного использования в различном приложении (т.е. регистратор) или b) если или из-за суммы параметров конструктора или потому что существует существенное количество логики в конструкторе, класс в других отношениях трудно дразнить.