接口的使用场景
接口在软件开发中广泛应用于解耦、标准化和多态实现。以下是常见的接口使用场景:
解耦组件依赖
通过接口定义交互规范,使模块间仅依赖抽象而非具体实现。例如:
// 定义数据访问接口
public interface UserRepository {
User findById(Long id);
}
// 业务层仅依赖接口
public class UserService {
private final UserRepository repository; // 接口依赖
}
多态实现
同一接口的不同实现可运行时替换。典型如支付网关:
interface PaymentGateway {
processPayment(amount: number): boolean;
}
class PayPalGateway implements PaymentGateway {
processPayment(amount: number) { … }
}
class StripeGateway implements PaymentGateway {
processPayment(amount: number) { … }
}
跨系统通信
REST API 和 RPC 接口规范不同系统间的数据交换:
# Flask 定义的 REST 接口
@app.route('/api/users/<id>', methods=['GET'])
def get_user(id):
return jsonify(User.query.get(id).serialize())
插件架构
通过接口允许第三方扩展功能:
public interface IPlugin {
string Name { get; }
void Execute();
}
// 主程序加载实现IPlugin的DLL
var plugin = Assembly.Load("Plugin.dll").CreateInstance("MyPlugin") as IPlugin;
测试替身
接口便于创建Mock对象进行单元测试:
// 测试用Mock实现
const mockUserService = {
getUser: jest.fn().mockResolvedValue({ id: 1, name: 'Test' })
};
// 测试代码注入Mock
userController.setService(mockUserService);
接口设计原则
单一职责
每个接口应聚焦单一功能。例如:
// 拆分存储和检索接口
interface UserWriter {
void save(User user);
}
interface UserReader {
User findById(Long id);
}
明确契约
接口应清晰定义输入输出及异常:
interface GeoCoder {
/**
* @throws InvalidAddressError 地址格式错误时抛出
*/
geocode(address: string): Promise<Coordinates>;
}
向后兼容
避免修改已发布的接口,通过版本控制或扩展实现演进:
GET /api/v2/users # 新版本接口
GET /api/v1/users # 保持旧版本可用
接口类型示例
标记接口
无方法的类型标记,如Java的Serializable:
public class DataPacket implements Serializable {
// 类实现
}
函数式接口
单一抽象方法的接口,支持Lambda:
@FunctionalInterface
interface StringProcessor {
String process(String input);
}
// Lambda实现
StringProcessor upper = str -> str.toUpperCase();
回调接口
异步操作结果通知:
function fetchData(callback: (data: any, error?: Error) => void) {
// 异步操作完成后调用callback
}



