让我们通过一个超级简单的真实示例来学习它:)
我要在这里讨论的示例类是一个Printer,它需要一个driver 来打印一些东西。我已经通过 4 个步骤展示了依赖注入设计模式的优势,最终得出最佳解决方案。
案例1:没有使用依赖注入:
class Printer {
constructor() {
this.lcd = '';
}
/* umm! Not so flexible! */
print(text) {
this.lcd = 'printing...';
console.log(`This printer prints ${text}!`);
}
}
// Usage:
var printer = new Printer();
printer.print('hello');
使用简单,用这种方法制作新打印机很容易,但是这个打印机不灵活。
案例 2: 将 print 方法中的功能抽象为一个名为 Driver 的新类:
class Printer {
constructor() {
this.lcd = '';
this.driver = new Driver();
}
print(text) {
this.lcd = 'printing...';
this.driver.driverPrint(text);
}
}
class Driver {
driverPrint(text) {
console.log(`I will print the ${text}`);
}
}
// Usage:
var printer = new Printer();
printer.print('hello');
所以我们的Printer 类现在更模块化、干净和容易理解,但又不灵活了。任何时候你使用new 关键字,你实际上是在硬编码 的东西。在这种情况下,您正在构建打印机内部的驱动程序,它在现实世界中是带有永远不会更改的内置驱动程序的打印机示例!
案例 3:将已制作的驱动程序注入您的打印机
更好的版本是在我们构建打印机时注入驱动程序
这意味着您可以制作任何类型的打印机,彩色或黑白,因为这
驱动程序被隔离并在Printer 类之外创建的时间,然后
给定(注入!)到Printer…
class Printer {
constructor(driver) {
this.lcd = '';
this.driver = driver;
}
print(text) {
this.lcd = 'printing...';
this.driver.driverPrint(text);
}
}
class BWDriver {
driverPrint(text) {
console.log(`I will print the ${text} in Black and White.`);
}
}
class ColorDriver {
driverPrint(text) {
console.log(`I will print the ${text} in color.`);
}
}
// Usage:
var bwDriver = new BWDriver();
var printer = new Printer(bwDriver);
printer.print('hello'); // I will print the hello in Black and White.
现在用法不同了,作为用户,为了拥有一台打印机,您首先需要
构造(制作)一个驱动程序(您选择!),然后将此驱动程序传递给您的打印机。看起来最终用户现在需要更多地了解系统,但是这种结构给了他们更多的灵活性。只要有效,用户就可以通过任何驱动程序!例如,假设我们有一个BWDriver(黑白)类型的驱动程序;用户可以创建一个这种类型的新驱动程序,并使用它来制作一台可以打印黑白的新打印机。
到目前为止一切顺利!但是你认为我们可以做得更好,你认为还有一些空间可以在这里解决吗?!我相信你也能看到!
我们正在创建一个新的打印机每次我们需要我们的打印机来打印
不一样的司机!那是因为我们将我们选择的驱动程序传递给
构建时的Printer 类;如果用户想要使用另一个驱动程序他们需要使用该驱动程序创建一个新的打印机。例如,如果我现在想进行彩色打印,我需要这样做:
var cDriver = new ColorDriver();
var printer = new Printer(cDriver); // Yes! This line here is the problem!
printer.print('hello'); // I will print the hello in color.
案例 4: 提供 setter 函数 随时设置打印机的驱动程序!
class Printer {
constructor() {
this.lcd = '';
}
setDriver(driver) {
this.driver = driver;
}
print(text) {
this.lcd = 'printing...';
this.driver.driverPrint(text);
}
}
class BWDriver {
driverPrint(text) {
console.log(`I will print the ${text} in Black and White.`);
}
}
class ColorDriver {
driverPrint(text) {
console.log(`I will print the ${text} in color.`);
}
}
// Usage:
var bwDriver = new BWDriver();
var cDriver = new ColorDriver();
var printer = new Printer(); // I am happy to see this line only ONCE!
printer.setDriver(bwDriver);
printer.print('hello'); // I will print the hello in Black and White.
printer.setDriver(cDriver);
printer.print('hello'); // I will print the hello in color.
依赖注入并不是一个很难理解的概念。这个词可能有点过头了,但一旦你意识到它的用途,你就会发现自己大部分时间都在使用它。