让我来详细讲解一下“深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP详解”的攻略。
接口隔离原则(Interface Segregation Principle,简称ISP),是S.O.L.I.D设计原则中的第四个原则。
它指出“客户端不应该依赖于它不需要的接口”。
简单来说,一个类应该仅对它需要使用的方法进行依赖,而不是依赖于其它不需要的方法。
在实际开发中,经常会遇到由一个接口提供多种方法的情况。如果一个类依赖于一个拥有多个方法的接口,而仅使用了其中的一部分方法,
那该类就会因为依赖无用的方法而被污染,从而使得这个类之间的函数耦合度变得更高。
当一个接口中包含的方法非常多,而我们的实现类中只需要使用其中的部分方法时,
如果我们不对这个接口进行一定的拆分,就会导致实现类实现接口中不需要的方法,这显然会造成一定的浪费。
为了遵守接口隔离原则,在设计接口的时候,需要将类似的方法放到一起,避免接口中出现无关的方法,并将较细的接口拆分成更小的和更具体的接口,
让接口的使用者只需知道与其相关的方法即可。
这样做的好处在于更改接口时不会影响到不需要关注的类,而且在使用的时候也不需要关注不必要的方法,减少了耦合度。
例如下面是一个违反接口隔离原则的实现示例:
class UserService {
constructor(database) {
this.database = database;
}
getAllUsers() {
// 返回所有用户的数据
}
getUserById() {
// 返回指定id用户的数据
}
updateUser() {
// 更新用户
}
deleteUser() {
// 删除用户
}
createUser() {
//创建用户
}
}
在这个例子中,所有的用户数据都需要通过UserService
这个类来进行读取、更新、删除和创建。
但是对于一些场景,我们可能只需要读取或创建用户而不需要更新或删除用户,如果我们使用UserService
,就会因为依赖了无用的方法而被污染。
为了符合ISP原则,我们可以将其拆分为更具体的接口:
interface IUserReader {
getAllUsers();
getUserById();
}
interface IUserCreator {
createUser();
}
interface IUserUpdater {
updateUser();
}
interface IUserDeleter {
deleteUser();
}
class UserService implements IUserReader, IUserCreator, IUserUpdater, IUserDeleter {
constructor(database) {
this.database = database;
}
getAllUsers() {
// 返回所有用户的数据
}
getUserById() {
// 返回指定id用户的数据
}
updateUser() {
// 更新用户
}
deleteUser() {
// 删除用户
}
createUser() {
//创建用户
}
}
通过拆分接口,我们就可以只依赖于需要使用的方法,而不会依赖不必要的方法。假设我们只需要读取用户信息,那么就只需要依赖IUserReader
接口即可。
除了单一职责原则、开闭原则和里式替换原则之外,接口隔离原则也是我们在实际开发中非常重要的一个设计原则。在大型的软件系统中,ISP原则可以使得代码的设计更加优美和可维护性更强。
一个优秀的设计模式应该是一个能够在需求更改时降低修改成本和工作量的系统架构,而接口隔离原则就是这种类型的优秀设计模式所必不可少的一部分。
我们需要在实际的工程项目中更加注重细节和拆分,不断提高对原则的理解和应用,从而能够更好的应对复杂的业务场景。
本文链接:http://task.lmcjl.com/news/11905.html