Это может прояснить несколько вещей:
Explanation of the UML arrows
Примечание Изображения для Visual Studio, но я думаю, что бы наиболее информации будет эквивалентна с большинством UML документации.
пунктирная линия представляет собой эквивалент «орудий»
Именование сущностей в UML бросает мне немного тоже ... похоже, что Policy
зависит от интерфейса, который описывает договор с модулем нижнего уровня Mechanism
Однако на второй (сплошной линии), которая должна представлять собой наследование (по крайней мере, я полагаю). Mechanism
реализует интерфейс (абстракция) Policy
, а не до применения DIP, когда Policy
ссылается на бетон Mechanism
.
То, что он пытается передать в основном, классы не должны зависеть от других классов, однако они могут зависеть от абстракций (интерфейсов), а не от бетонов.
Самый простой пример: Оригинальный Foo/Logger с зависимостями от модулей нижнего уровня.
// "Low level Module" Mechanism equivilant
public class Logger {
public void logInformation(String logInfo) {
System.out.println(logInfo);
}
}
// "High level module" Policy equivalent.
public class Foo {
// direct dependency of a low level module.
private Logger logger = new Logger();
public void doStuff() {
logger.logInformation("Something important.");
}
}
В приведенном выше описании, Foo
зависит от конкретной реализации Logger
. Это может быть переработано как таковое (примечание есть несколько способов сделать это, это только один)
public interface ILogger {
void logInformation(String logInfo);
}
public class Logger implements ILogger {
@Override
public void logInformation(string logInfo) {
System.out.println(logInfo);
}
}
public class Foo {
private ILogger logger;
public void setLoggerImpl(ILogger loggerImpl) {
this.logger = loggerImpl;
}
public void doStuff() {
logger.logInformation("Something important.");
}
}
В этом реорганизовать, Foo
больше не зависит от Logger
, но теперь использует интерфейс ILogger
- это означает, что вам может переключаться в и из реализаций ILogger во время выполнения, объект конкретизации и т.д.
Вы могли бы потреблять Foo
как таковой:
Foo foo = new Foo();
ILogger logger = new Logger();
foo.setLoggerImpl(logger);
foo.doStuff();
Это, конечно, печать для консоли «Что-то важное».Теперь, что произойдет, если вы не хотите регистрироваться на консоли, а в базе данных?
public class LoggerToDb implements ILogger {
@Override
public void logInformation(string logInfo) {
DbContext databaseContext = new DbContext();
databaseContext.insertLog(logInfo);
}
}
и теперь можно употреблять в пищу:
Foo foo = new Foo();
ILogger logger = new LoggerToDb();
foo.setLoggerImpl(logger);
foo.doStuff();
Обратите внимание, как ничего не было изменить в Foo
реализации, поскольку Foo
не зависит от Logger
, но вместо ILogger
- с таким подходом мы можем обеспечить новая конкреция с абстракцией, и замените ее на Foo
, даже не касаясь Foo
! Довольно неато ИМО.
Примечание: в приведенных выше примерах я создаю объект и предоставляю реализацию, это также можно сделать с помощью инфраструктуры IOC, такой как Spring Java.
@LuiggiMendoza спасибо, никогда бы не получил этот синтаксис правильно :) – Kritner
Я думаю, что вы смешиваете инъекцию зависимостей и инверсию зависимостей. DIP применяется к межмодульным зависимостям и является улучшением по сравнению с стандартной многоуровневой архитектурой. Основное внимание уделяется отношениям между модулями. [Более подробная информация здесь] (https://books.google.ca/books?id=X7DpD5g3VP8C&pg=PA123&lpg=PA123&dq=improved+layered+architecture+dependency+inversion+principle&source=bl&ots=tRBNLGD9YS&sig=8Zrz_2ANj29vXYNnEAHssA95dGI&hl=fr&sa=X&ei=dD44VdfdGozToAThh4HwAQ&ved= 0CCgQ6AEwAQ # v = onepage & q = улучшенный% 20layered% 20architecture% 20dependency% 20inversion% 20principle & f = false) – plalx
@plalx hmm ... У меня создалось впечатление, что DI - это один из способов выполнения DIP - я специально не называл это в своем пример (как он был вызван в цитированной статье wiki), но 'ILogger' принадлежит« Foo', а не «Logger» или любые другие реализации «ILogger». Из того, что я прочитал, который описывает DIP ... можете ли вы прояснить, что пропустили? – Kritner