七大设计原则(二)--接口隔离原则ISP

接口隔离原则(Interface Segregation Principle, ISP)

接口隔离原则的宗旨就是类实现接口时, 不要强迫一个类去实现它用不到的方法

保持类与接口之间是最小依赖的状态
违反接口隔离原则的Java示例:

java 复制代码
interface ConnectDBInterface {
    // 所有数据库通用的核心方法(合理)
    void setHost(String host);
    void setPort(int port);
    void setUsername(String username);
    void setPassword(String password);
    void connect(); // 建立连接
    void close(); // 关闭连接

    // MySQL 专属方法(其他数据库用不上)
    void setSocketPath(String path); // MySQL 可通过 socket 文件连接
    void setUseSSL(boolean useSSL); // MySQL 的 SSL 配置

    // PostgreSQL 专属方法(其他数据库用不上)
    void setDatabaseName(String dbName); // PostgreSQL 必须指定数据库名
    void setSchema(String schema); // PostgreSQL 的 Schema 配置

    // Oracle 专属方法(其他数据库用不上)
    void setSID(String sid); // Oracle 的实例ID
    void setServiceName(String serviceName); // Oracle 的服务名
}

// MySQL 实现类:被迫实现一堆用不上的方法
class MySQLConnector implements ConnectDBInterface {
    // 通用方法:正常实现
    @Override public void setHost(String host) { /* 实现 */ }
    @Override public void setPort(int port) { /* 实现 */ }
    @Override public void setUsername(String username) { /* 实现 */ }
    @Override public void setPassword(String password) { /* 实现 */ }
    @Override public void connect() {
        System.out.println("MySQL 连接成功:");
    }
    @Override public void close() { System.out.println("MySQL 连接关闭"); }

    // MySQL 专属方法:正常实现
    @Override public void setSocketPath(String path) { /* 实现 */ }
    @Override public void setUseSSL(boolean useSSL) { /* 实现 */ }

    // 用不上的 PostgreSQL/Oracle 方法:只能空实现或抛异常(冗余且不合理)
    @Override public void setDatabaseName(String dbName) {
        throw new UnsupportedOperationException("MySQL 不支持设置 DatabaseName");
    }
    @Override public void setSchema(String schema) {
        throw new UnsupportedOperationException("MySQL 不支持设置 Schema");
    }
    @Override public void setSID(String sid) {
        throw new UnsupportedOperationException("MySQL 不支持 SID");
    }
    @Override public void setServiceName(String serviceName) {
        throw new UnsupportedOperationException("MySQL 不支持 ServiceName");
    }
}

// PostgreSQL 实现类:同样被迫实现无用方法
class PostgreSQLConnector implements ConnectDBInterface {
    @Override public void setHost(String host) { /* 实现 */ }
    @Override public void setPort(int port) { /* 实现 */ }
    @Override public void setUsername(String username) { /* 实现 */ }
    @Override public void setPassword(String password) { /* 实现 */ }
    @Override public void connect() {
        System.out.println("PostgreSQL 连接成功:");
    }
    @Override public void close() { System.out.println("PostgreSQL 连接关闭"); }

    // PostgreSQL 专属方法:正常实现
    @Override public void setDatabaseName(String dbName) { /* 实现 */ }
    @Override public void setSchema(String schema) { /* 实现 */ }

    // 用不上的 MySQL/Oracle 方法:被迫抛异常
    @Override public void setSocketPath(String path) { throw new UnsupportedOperationException(); }
    @Override public void setUseSSL(boolean useSSL) { throw new UnsupportedOperationException(); }
    @Override public void setSID(String sid) { throw new UnsupportedOperationException(); }
    @Override public void setServiceName(String serviceName) { throw new UnsupportedOperationException(); }
}

不合理的万能接口设计导致在具体的类实现时需要被迫处理很多用不到的类方法

合理的接口设计如下:

java 复制代码
// 1. 通用数据库连接接口(所有数据库都需要的核心功能,最小化设计)
interface BaseDBConnector {
    void setHost(String host);
    void setPort(int port);
    void setUsername(String username);
    void setPassword(String password);
    void connect(); // 核心:建立连接
    void close(); // 核心:关闭连接
}

// 2. MySQL 专属接口(只包含 MySQL 特有的功能)
interface MySQLSpecific {
    void setSocketPath(String path); // MySQL 专属:socket 文件连接
    void setUseSSL(boolean useSSL); // MySQL 专属:SSL 配置
}

// 3. PostgreSQL 专属接口(只包含 PostgreSQL 特有的功能)
interface PostgreSQLSpecific {
    void setDatabaseName(String dbName); // PostgreSQL 专属:数据库名(必填)
    void setSchema(String schema); // PostgreSQL 专属:Schema 切换
}

// 4. Oracle 专属接口(只包含 Oracle 特有的功能)
interface OracleSpecific {
    void setSID(String sid); // Oracle 专属:实例ID
    void setServiceName(String serviceName); // Oracle 专属:服务名
}

// ---------------------- 子类实现(按需组合接口)----------------------
// MySQL 连接器:实现「通用接口 + MySQL 专属接口」
class MySQLConnector implements BaseDBConnector, MySQLSpecific {
    // 实现通用接口方法
    @Override public void setHost(String host) { /* 实现 */ }
    @Override public void setPort(int port) { /* 实现 */ }
    @Override public void setUsername(String username) { /* 实现 */ }
    @Override public void setPassword(String password) { /* 实现 */ }
    @Override public void connect() {
        System.out.println("MySQL 连接成功:");
    }
    @Override public void close() { System.out.println("MySQL 连接关闭\n"); }

    // 实现 MySQL 专属接口方法
    @Override public void setSocketPath(String path) { /* 实现 */ }
    @Override public void setUseSSL(boolean useSSL) { /* 实现 */ }
}

// PostgreSQL 连接器:实现「通用接口 + PostgreSQL 专属接口」
class PostgreSQLConnector implements BaseDBConnector, PostgreSQLSpecific {
    // 实现通用接口方法
    @Override public void setHost(String host) { /* 实现 */ }
    @Override public void setPort(int port) { /* 实现 */ }
    @Override public void setUsername(String username) { /* 实现 */ }
    @Override public void setPassword(String password) { /* 实现 */ }
    @Override public void connect() {
        System.out.println("PostgreSQL 连接成功:");
    }
    @Override public void close() { System.out.println("PostgreSQL 连接关闭\n"); }

    // 实现 PostgreSQL 专属接口方法
    @Override public void setDatabaseName(String dbName) { /* 实现 */ }
    @Override public void setSchema(String schema) { /* 实现 */ }
}

// Oracle 连接器:实现「通用接口 + Oracle 专属接口」
class OracleConnector implements BaseDBConnector, OracleSpecific {
    // 实现通用接口方法(省略 setHost/setPort 等重复代码,逻辑和上面一致)
    @Override public void setHost(String host) { /* 实现 */ }
    @Override public void setPort(int port) { /* 实现 */ }
    @Override public void setUsername(String username) { /* 实现 */ }
    @Override public void setPassword(String password) { /* 实现 */ }
    @Override public void connect() {
        System.out.println("Oracle 连接成功:");
    }
    @Override public void close() { System.out.println("Oracle 连接关闭\n"); }

    // 实现 Oracle 专属接口方法
    @Override public void setSID(String sid) { /* 实现 */ }
    @Override public void setServiceName(String serviceName) { /* 实现 */ }
}

BaseDBConnector 接口中只保留所有数据库通用的方法, 各个子类实现则规定各自独有的接口方法, 实现类中不需要多余的异常处理. 各个子类之间完全独立, 松耦合.

相关推荐
黑妹天下第一乖2 天前
第 12 讲:阿加犀 AidLux 部署与量产——把端侧 AI 应用做成 7×24 产品
人工智能·嵌入式硬件·数码相机·接口隔离原则·iot
黑妹天下第一乖3 天前
第08讲 · 视觉与相机流水:Spectra ISP 与实时检测
人工智能·嵌入式硬件·数码相机·机器人·接口隔离原则·iot
pride.li8 天前
ISP标定-BLC标定(Black Level Calibration,黑电平校准)
人工智能·计算机视觉·接口隔离原则
kyle~1 个月前
ISP---RAW数据解析:从PixelFormat、Packed_Buffer到Bayer解码
数码相机·接口隔离原则
FLJwu1 个月前
镜头模组与画质量产实战 03:运动相机 ISP 图像调校、杂光鬼影抑制与来料验收标准|20 年源头工厂量产经验
经验分享·数码相机·产品运营·接口隔离原则·相机
kyle~1 个月前
ISP---RAW 成像的物理基础
计算机视觉·接口隔离原则·相机
kyle~1 个月前
ISP--- RAW 图像 从传感器噪声模型到快门时序与频闪效应
人工智能·计算机视觉·接口隔离原则
PHP实战开发录1 个月前
PHP接口参数没变为什么总是验签失败
php·开发·接口隔离原则
啊阿狸不会拉杆1 个月前
《计算机网络-自顶向下方法》5.4 ISP之间的路由选择:BGP 读书笔记
网络·计算机网络·接口隔离原则
运维行者_1 个月前
ISP 企业级带宽计费怎么做?网络流量计费的 6 大核心能力
运维·服务器·网络·数据库·支持向量机·接口隔离原则