我最近正在阅读一篇关于SOLID原则的文章,我似乎无法理解有关依赖性反转原则(DIP)的示例。文章给出了以下示例。首先是不正确的方式,然后是正确的方式。
不正确的方式
class Login {
login(googleLogin: any) {
// some code which will be used for google login.
}
}
有道理,文章解释说,如果客户想明天添加Facebook登录,则必须修改Login类,这对于DIP来说不是必需的。取决于抽象而非结核。理解。
正确的方式
interface ISocialLogin {
login(options: any);
}
class GoogleLogin implements ISocialLogin {
login(googleLogin: any) {
// some code which will be used for google login.
}
}
class FBLogin implements ISocialLogin {
login(fbLogin: any) {
// some code which will be used for fb login.
}
}
class Login {
constructor(private login: ISocialLogin) {}
onLogin() {
this.login();
}
}
现在,在这个例子中..我们如何知道Login类将使用哪个类?我可以看到你在构造函数中是否指定了GoogleLogin和FBLogin,但是实现该接口对我来说很困惑。有人可以解释一下吗?提前谢谢。
编辑其他问题...
我仍然缺少一些基本的东西。在这个例子中(特定于Angular),假设我有以下UX。在LoginComponent内部,我有一个GoogleLoginComponent和一个FacebookLoginComponent。在这两个子组件示例中,我将使用GoogleLogin和FBLogin类,对吗?
答案 0 :(得分:3)
TL; DR:zerkms在评论中给出了正确答案。
答案很长:
这个问题的依赖倒置原则的要点是,您的Login实现独立于ISocialLogin
的实际实现。您必须仅使用ISocialLogin
提供的属性和方法,但只要作为Login
构造函数的参数接收的类实现它们,您的组件将独立于底层登录实现
这里的诀窍是现在登录不需要选择用于登录实现的实例,因为它是从外部提供的。这样您就可以在任何地方使用Login+ISocialLogin
组件。例如,一个新应用程序可能提供不同的社交登录实现,您将能够重用该组件。在前者(即不正确的方式)中,构造函数以及使用它的Login
中的任何其他方法都需要重做,因为它依赖于GoogleLogin
实现。
总而言之,你已经离开了这种依赖(由括号分隔的单独组件;箭头方向意味着“取决于”):
(Login) -> (GoogleLogin)
为:
(Login -> ISocialPlugin) <- (GoogleLogin)