接口设计原则理解与思考
一、单一职责原则(SRP)
概念
单一职责原则(Single Responsibility Principle,SRP)是软件开发中的一种设计原则,它的核心思想是:一个类(或模块)应该仅有一个引起它变化的原因。换句话说,每个类(或模块)应该只有一个职责,只有一个功能。这有助于保持代码的可维护性、可读性和可扩展性。
单一职责原则是面向对象设计中的SOLID原则之一,具体含义如下:
高内聚、低耦合:类的职责单一,能使类的内部高度内聚,并减少类与类之间的耦合。
代码复用性:职责单一的类更加模块化,更容易被其他代码复用。
可读性和可维护性:职责单一的类更容易理解,也更容易维护和修改。当某个功能需要修改时,只需修改相关的单一类,而不会影响其他不相关的功能。
测试性:职责单一的类更容易编写单元测试,因为测试的范围更小,更集中。
二、开闭原则(OCP)
概念
开闭原则(Open/Closed Principle,OCP)是面向对象设计中的一个核心原则。其主要思想是:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。换句话说,当软件需求变化时,我们应该通过扩展现有的代码,而不是修改已有的代码来实现变化。
开闭原则有助于提高软件系统的可维护性和可扩展性,减少因为修改已有代码而引入错误的风险。
实现开闭原则的方法
- 抽象:使用接口或抽象类来定义不变的部分,通过继承和实现这些接口或抽象类来扩展新的功能。
- 组合:通过组合现有对象来实现新功能,而不是修改现有对象的内部代码。
三、里氏替换原则(LSP)
概念
里氏替换原则(Liskov Substitution Principle,LSP)是面向对象设计中的一个重要原则,它由Barbara Liskov在1987年提出。这个原则的核心思想是:子类对象应该可以替换父类对象,并且程序行为不会发生变化。换句话说,任何使用基类对象的地方,都可以使用其子类对象而不影响程序的正确性。
里氏替换原则强调的是继承关系中子类与父类之间的行为一致性,确保子类在扩展父类时,不会违背父类的约定。
里氏替换原则的实现方法
- 行为一致性:子类重写父类的方法时,应该保持方法的行为和语义一致。
- 输入输出一致性:子类的方法参数类型和返回值类型应该与父类保持一致或更为严格。
- 不破坏父类的预期功能:子类不应引入违反父类预期的新行为或约束。
四、接口隔离原则(ISP)
概念
接口隔离原则(Interface Segregation Principle,ISP)是面向对象设计中的一个重要原则。这个原则的核心思想是:客户端不应该被迫依赖于它不使用的方法。换句话说,接口应该尽量小而专一,避免臃肿的、包含许多方法的“大接口”。ISP 鼓励设计小而具体的接口,使得客户端只需关心和实现自己所需的方法。
实现接口隔离原则的方法
- 细化接口:将大接口拆分为多个小接口,每个接口只包含相关的方法。
- 接口组合:可以通过组合小接口来构建复杂的接口,使得每个接口都保持单一职责。
五、依赖反转原则(DIP)
概念
依赖反转原则(Dependency Inversion Principle,DIP)是面向对象设计中的一个关键原则,它的核心思想是:高层模块不应该依赖于低层模块,二者都应该依赖于抽象;抽象不应该依赖于具体实现,具体实现应该依赖于抽象。这个原则旨在减少模块之间的耦合,提高系统的灵活性和可维护性。
实现依赖反转原则的方法
- 使用接口或抽象类:定义抽象层,使高层模块依赖于抽象层,而不是具体的实现。
- 依赖注入:通过构造函数注入、方法注入或属性注入等方式,将依赖传递给需要它们的对象,而不是在对象内部直接创建依赖。
六、幂等性
6.1 概念
幂等性(Idempotency)是计算机科学和编程中的一个重要概念,特别是在分布式系统和网络通信中,它指的是某个操作可以重复执行多次而不会改变结果。换句话说,无论执行该操作多少次,系统的状态都保持不变。
幂等性在许多应用场景中都非常重要,例如:
- Web服务和API:在网络通信中,由于网络不可靠,可能会出现请求超时或者重复发送请求的情况。如果API操作是幂等的,即使客户端重复发送请求,服务器的状态也不会发生意外的变化。
- 数据库操作:某些数据库操作需要保证幂等性,以防止由于重试机制导致的数据不一致问题。
- 分布式系统:在分布式系统中,由于网络分区、节点故障等问题,操作可能会被多次执行,幂等性可以保证系统的稳定性和一致性。
在常规请求方法中,get、put、delete请求通常是幂等的,无论调用多少次都能保持状态不变;Post请求则是非幂等的,每次调用都会创建一个新的资源。
6.2 实现幂等性的方法
在设计系统时,我们可以采取一些措施来确保操作的幂等性:
- 使用唯一标识符: 通过为每个操作分配唯一的标识符,可以确保即使重复提交请求,服务器也能识别并忽略重复的操作。例如,支付系统中的每笔交易都有唯一的交易ID。
- 状态检查: 在执行操作之前检查当前状态,如果状态已经符合预期,则无需再次执行操作。例如,在更新数据库记录时,可以先检查记录是否已经具有预期的值。
- 写操作的幂等性: 对于需要幂等性的写操作,可以使用类似UPSERT(UPDATE或INSERT)的数据库操作,确保即使操作多次,结果也是一致的。
6.3 应用
1、在数据库层面,应当保持唯一的合理采用唯一索引,确保异常数据在数据库层面被拦截。
2、结合唯一索引和业务,必要时使用for update悲观锁加上行锁,确保业务数据的一致性。
3、结合数据库字段和业务,使用表中某个字段进行版本判断,此种方法属于乐观锁。
1点在大量服务中应用,2,3点目前主要应用沽清服务,沽清服务涉及库存,对于数据一致性。数据的更新频率有一定要求,因此采用乐观锁和悲观锁二者一起维护数据一致性。
6.4 总结
幂等性是构建可靠、稳定和一致性系统的重要特性。通过设计幂等的API和操作,我们可以有效地处理网络通信中的重复请求和失败重试问题,提高系统的健壮性和用户体验。在实际开发中,合理使用唯一标识符、状态检查和幂等写操作等技术手段,可以有效地实现幂等性。