基于TypeScript的SOLID原则之依赖倒置原则(DIP)示例解惑
搞懂依赖倒置原则(DIP)的正确实现:从代码拆解入手
我完全懂你这种“道理都懂但看具体实现还是摸不着头脑”的感觉!咱们直接用代码把DIP的正确实现拆解开,一步步看它是怎么做到“新增功能不用修改原有核心类”的。
先看你提到的「错误实现」
假设原来的代码是这样的——Login类直接依赖GoogleLogin、WeChatLogin这些具体的登录实现:
// 具体的Google登录实现 class GoogleLogin { public boolean login(String username, String password) { // Google登录逻辑 return true; } } // 具体的微信登录实现 class WeChatLogin { public boolean login(String openId, String token) { // 微信登录逻辑 return true; } } // 核心登录类 class Login { public boolean doGoogleLogin(String username, String password) { GoogleLogin googleLogin = new GoogleLogin(); return googleLogin.login(username, password); } public boolean doWeChatLogin(String openId, String token) { WeChatLogin weChatLogin = new WeChatLogin(); return weChatLogin.login(openId, token); } }
这时候要加Facebook登录,就必须修改Login类,新增一个doFacebookLogin方法,还得实例化FacebookLogin的具体类——完全违反了开闭原则,也没做到DIP。
再看「遵循DIP的正确实现」
关键就是先定义抽象层,让高层模块(Login)和低层模块(各种登录实现)都依赖这个抽象,而不是互相依赖。
第一步:定义抽象的登录接口
先搞一个通用的登录行为抽象,不管是Google、微信还是Facebook,都得遵循这个接口的规则:
// 抽象的登录提供者接口 interface LoginProvider { boolean authenticate(String credential1, String credential2); }
第二步:让具体登录实现类实现这个接口
把原来的具体登录类都改成实现这个接口,统一登录方法的签名:
class GoogleLogin implements LoginProvider { @Override public boolean authenticate(String username, String password) { // Google登录逻辑:用账号密码验证 return true; } } class WeChatLogin implements LoginProvider { @Override public boolean authenticate(String openId, String token) { // 微信登录逻辑:用openId和token验证 return true; } } // 新增Facebook登录时,只需要加这个类,不用改任何原有代码! class FacebookLogin implements LoginProvider { @Override public boolean authenticate(String fbId, String accessToken) { // Facebook登录逻辑 return true; } }
第三步:改造核心Login类,依赖抽象而非具体实现
现在Login类不再直接依赖某个具体的登录类,而是依赖LoginProvider这个抽象接口,通过依赖注入的方式接收具体的实现:
class Login { private LoginProvider loginProvider; // 构造注入:传入具体的登录提供者 public Login(LoginProvider loginProvider) { this.loginProvider = loginProvider; } // 统一的登录方法,不管是什么登录方式,都走这一个方法 public boolean doLogin(String credential1, String credential2) { return loginProvider.authenticate(credential1, credential2); } }
为什么这就符合DIP了?
- 高层模块(Login)不再依赖低层模块(GoogleLogin、WeChatLogin等),而是依赖抽象(LoginProvider)
- 低层模块也依赖同一个抽象(所有登录实现都实现LoginProvider)
- 新增Facebook登录时,只需要加一个
FacebookLogin实现类,然后在调用Login的时候传入这个实例就行:// 用Google登录 Login googleLogin = new Login(new GoogleLogin()); googleLogin.doLogin("user123", "pass456"); // 用Facebook登录(新增功能,完全没改Login类) Login facebookLogin = new Login(new FacebookLogin()); facebookLogin.doLogin("fb_789", "token_abc");
这样就彻底做到了“新增功能无需修改原有核心代码”,完美体现了DIP的核心:依赖抽象,而非具体实现。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

