Oop 解释这张关于依赖倒置原理的动机海报

Oop 解释这张关于依赖倒置原理的动机海报,oop,dependencies,solid-principles,dependency-inversion,Oop,Dependencies,Solid Principles,Dependency Inversion,在博客文章中,这张激励海报描述了依赖倒置原则: 我不明白海报是什么意思:把灯直接焊接到墙上是如何违反依赖倒置原则的,插头是如何遵循依赖倒置原则的。也许一些关于灯和电源插座的Java或C#代码框架可能会有所帮助。这是一个类比,用于将不硬编码的常见做法,例如控制器(控制流的类)与模型(数据来源)进行类比 例如,这将是不好的、不可测试的或容易“拔出”: 而是将存储库注入控制器: public function __construct(Somerepo $repo) { $this->

在博客文章中,这张激励海报描述了依赖倒置原则:


我不明白海报是什么意思:把灯直接焊接到墙上是如何违反依赖倒置原则的,插头是如何遵循依赖倒置原则的。也许一些关于灯和电源插座的Java或C#代码框架可能会有所帮助。

这是一个类比,用于将不硬编码的常见做法,例如控制器(控制流的类)与模型(数据来源)进行类比

例如,这将是不好的、不可测试的或容易“拔出”:

而是将存储库注入控制器:

public function __construct(Somerepo $repo)
{ 
    $this->repo = $repo;
}
然后,您可以继续通过repo中的方法访问所需的SQL语句

public function index()
{
     return $this->repo->getStuff();
}
通过这种方式,您可以轻松更改或“拔下”数据来源,而无需触碰控制器逻辑。

从您的链接:

实线中的“D”表示依赖项反转原理,表示 高级模块不应该依赖于低级模块,而是 两者都应该依赖于共享的抽象

我不知道“共享”抽象是什么意思。在代码中,指示灯将是“高级模块”,而它的电源将来自于它的依赖关系,或“低级模块”

你的问题:

将灯直接焊接到墙上是如何违反依赖倒置原则的

海报中的灯违反了依赖倒置原则,因为它不依赖抽象电源。它依赖于一个非常具体的实现,直接焊接到墙上的电线上。如果此关系是在代码中建模的,它可能看起来像这样:

public class Lamp {
    // This part is the equivalent of "soldering a lamp directly to the electrical wiring in a wall"
    private ElectricalWiringInBobsWall electricalWiring = new ElectricalWiringInBobsWall();
    private boolean isOn; 

    public void turnOn() {
        electricalWiring.useElectricityInWatts(60);
        isOn = true;
    }

    public void turnOff() {
        electricalWiring.turnOffElectricityInWatts(60);
        isOn = false;
    }   
}
public interface Outlet {
    void useElectricityInWatts(int watts);
    void turnOffElectricityInWatts(int watts);
}   

public class Lamp {
    private Outlet outlet;
    private boolean isOn; 

    // We pass in the dependency instead of instantiating it and rely on an interface (abstraction)
    public void plugInto(Outlet outlet) {
        this.outlet = outlet;
    }

    public void turnOn() {
        outlet.useElectricityInWatts(60);
        isOn = true;
    }

    public void turnOff() {
        outlet.turnOffElectricityInWatts(60);
        isOn = false;
    }   
}
这样做的后果是,灯很难在其他情况下使用。在现实生活中,如果你想把灯移到房子的另一个地方,在发电机上使用,或者甚至把它带到国外并插到另一个插座上,灯本身就需要大量的返工。类似地,在一个代码库中,如果您想用不同的电源重复使用这个灯,您必须更改灯本身的代码,这可能需要重新测试,或者引入新的bug

使用插件如何遵循依赖倒置原则

插座更为抽象,因为作为用户,您实际上不必知道灯是如何获得电源的。你所要知道的是,如果你把灯插上,它就会工作。插座是对电源的抽象。也就是说,它隐藏了权力实际来自何处的细节。墙壁上、发电机上、海外适配器上、太阳能电池板电源上都可能有插座,等等

在上面的类中使用DIP,我们希望
Lamp
依赖于抽象,并将实现作为依赖项传入。在代码中,这可能如下所示:

public class Lamp {
    // This part is the equivalent of "soldering a lamp directly to the electrical wiring in a wall"
    private ElectricalWiringInBobsWall electricalWiring = new ElectricalWiringInBobsWall();
    private boolean isOn; 

    public void turnOn() {
        electricalWiring.useElectricityInWatts(60);
        isOn = true;
    }

    public void turnOff() {
        electricalWiring.turnOffElectricityInWatts(60);
        isOn = false;
    }   
}
public interface Outlet {
    void useElectricityInWatts(int watts);
    void turnOffElectricityInWatts(int watts);
}   

public class Lamp {
    private Outlet outlet;
    private boolean isOn; 

    // We pass in the dependency instead of instantiating it and rely on an interface (abstraction)
    public void plugInto(Outlet outlet) {
        this.outlet = outlet;
    }

    public void turnOn() {
        outlet.useElectricityInWatts(60);
        isOn = true;
    }

    public void turnOff() {
        outlet.turnOffElectricityInWatts(60);
        isOn = false;
    }   
}
现在,一盏灯可以使用任何类型的插座:BobsOutletInHisWall、GeneratorOutlet、EuropeanAdapterOutlet等。它可以很容易地在其他情况下移动和使用,而且根本不需要更换


我知道这个例子还远远不够完美,但我希望这能解释海报的含义。

请回答更多以“解释这张激励海报”开头的问题!