You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:14:04