我们已经学习了SOLID原则的一半!今天我们来学习“I”:接口隔离原则。
想要理解这个原则,我们首先需要了解什么是接口。接口是一组可以在类中实现的方法的定义。每个实现该接口的类都必须使用接口中包含的所有方法。因为接口仅定义了方法签名(名称、参数和返回类型),所以这些方法在每个实现中可能有所不同。
接口隔离原则指出,任何类都不应该被迫依赖于它不使用的方法。为了理解这一点,让我们来看一个例子。假设你要测试一个网站,它有两种不同的表单:雇员表单和雇主表单。因此,当你决定创建一个Form接口,其中包含与表单中各种对象交互的方法:
interface Form {
fillInTextField(id: String, value: String): void;
selectRadioButton(id: String): void;
checkCheckbox(id: String): void;
}
创建EmployeeForm类时,要让它实现Form接口:
class EmployeeForm implements Form {
fillInTextField(id: String, value: String): void {
driver.findElement(By.id(id)).sendKeys(value)
}
selectRadioButton(id: String): void {
driver.findElement(By.id(id)).click()
}
checkCheckbox(id: String): void {
driver.findElement(By.id(id)).click()
}
}
这样做效果很好,因为雇员表单有文本字段、单选按钮和复选框。
接下来,你创建了一个EmployerForm类,它也实现了Form接口。但是这个表单只有文本字段,没有单选按钮或复选框。因此,你按照如下方式实现这个接口:
class EmployerForm implements Form {
fillInTextField(id: String, value: String): void {
driver.findElement(By.id(id)).sendKeys(value)
}
selectRadioButton(id: String): void {
// no radio button
throw new Error("No radio button exists");
}
checkCheckbox(id: String): void {
// no checkbox
throw new Error("No checkbox exists");
}
}
你永远不会在EmployerForm类中调用 selectRadioButton 和 checkCheckbox 方法,因为该表单中没有单选按钮或复选框,但出于接口的需要,你仍然需要为它们创建方法。这违反了接口隔离原则。
那么,如何在不违反原则的情况下使用这些表单的接口呢?你可以为文本字段、单选按钮和复选框创建单独的接口,如下所示:
interface TextField {
fillInTextField(id: String, value: String): void;
}
interface RadioButton {
selectRadioButton(id: String): void;
}
interface Checkbox {
checkCheckbox(id: String): void;
}
然后,当你创建EmployeeForm类时,可以像下面这样实现三个接口:
class EmployeeForm implements TextField, RadioButton, Checkbox {
fillInTextField(id: String, value: String): void {
driver.findElement(By.id(id)).sendKeys(value)
}
selectRadioButton(id: String): void {
driver.findElement(By.id(id)).click()
}
checkCheckbox(id: String): void {
driver.findElement(By.id(id)).click()
}
}
现在,当你创建EmployerForm类时,只需实现 TextField 接口即可:
class EmployerForm implements TextField {
fillInTextField(id: String, value: String): void {
driver.findElement(By.id(id)).sendKeys(value)
}
}
当每个类只需要实现其所需的方法时,类就变得更加容易维护。拥有更小的接口意味着它们可以在更广泛的场景中使用。这就是接口隔离原则的好处。