接口隔离原则(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 接口中只保留所有数据库通用的方法, 各个子类实现则规定各自独有的接口方法, 实现类中不需要多余的异常处理. 各个子类之间完全独立, 松耦合.