Recently, I came across an intriguing article discussing the SOLID principles and delving into the concept of the Dependency Inversion Principle (DIP). The article presented an example to illustrate this principle using both an incorrect and a correct approach.
INCORRECT WAY
class Login {
login(googleLogin: any) {
// some code which will be used for google login.
}
}
The article pointed out that in this incorrect way, if there was a need to add Facebook login functionality later, it would require modifying the Login class. This goes against the DIP philosophy of being dependent on abstractions rather than concrete implementations. It started to make sense to me at this point.
CORRECT WAY
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();
}
}
However, I found myself puzzled by one aspect of this correct approach. How does the Login class know which social login class to use? Simply implementing the interface doesn't seem clear to me. Can someone provide further clarification on this topic? Many thanks in advance.
Edit - Additional Question:
I'm still grappling with some basic concepts here. Let's consider an Angular-specific scenario. Imagine a LoginComponent containing GoogleLoginComponent and FacebookLoginComponent. Should I utilize the GoogleLogin and FBLogin classes within these child components as demonstrated in the image provided?