"optional" 方法在实现中的接口隔离原则
Interface Segregation Principle with "optional" methods in Implementation
SOLID 的接口隔离原则说 类 不应该 implement/depend 他们不需要的方法。你不应该有
//Not used: just needed to implement interface
在代码库中。
当一些方法本质上是 "optional" 时,我该如何应用这个原则,因为实现 class 是一个特定的极端情况。
假设我有这个界面示例:
Interface Input {
Input create();
void capitalizeInput(CAPITALIZATION cap);
String getInput();
}
Class LatinInput implements Input {
String input;
Input create(String input){...}
void capitalizeInput(CAPITALIZATION cap){...}
String getInput(){...}
}
Class NumberOnlyInput implements Input {
int input;
Input create(int input){...}
void capitalizeInput(CAPITALIZATION cap){
// Needed because the interface requires it.
return;
}
String getInput(){...}
}
该接口被其他 classes 在程序中广泛使用。目前在我的程序中,我正在做类似以下的事情。
Class B {
Input input;
B(Input input){
this.input = input;
}
String doStuff(){
...
methodA();
...
methodB();
...
methodC();
...
methodA();
...
return ...;
}
private void methodA(){
...
input.transformInput(CAPITAL);
input.getInput();
}
private void methodB(){
...
input.getInput();
}
private void methodC(){
...
input.transformInput();
}
}
并且被C类调用;
Class C {
void doStuff() {
List<A> list = new Arraylist<>();
list.add(LatinInput.create("hello"));
list.add(LatinInput.create("goodbye"));
list.add(NumberOnlyInput.create(12345));
for(Input input: list){
B b = new B(a);
b.doStuff();
}
}
}
我应该如何更改设计以符合 ISP,而不更改 class C,同时也不需要在运行时检查对象是否 instance of
?
Interface segregation principle:
states that no client should be forced to depend on methods it does not use.
它没有说任何关于用空主体实现方法的事情。你的classB
同时使用了capitalizeInput
和getInput
,只要是Input
中的两个方法,就不会违反接口隔离原则。在您的情况下 B
使用 NumberOnlyInput.capitalizeInput
碰巧 empy body 是此功能的有效实现。
但是,Input.create
确实违反了ISP。 B
依赖于 Input
但不使用 Input.create
- 它根本没有被调用。在这种情况下,您可以将其从界面中删除。
你仍然可以摆脱那个奇怪的空方法。由于 NumberOnlyInput
是 LatinInput
的特例,您可以重复使用 class:
class NumberOnlyInput {
static Input create(int input) {
return new LatinInput(String.valueOf(input));
}
}
它可能不太清晰或不太高效 - 这可能就是为什么首先创建数字的特殊情况。
SOLID 的接口隔离原则说 类 不应该 implement/depend 他们不需要的方法。你不应该有
//Not used: just needed to implement interface
在代码库中。
当一些方法本质上是 "optional" 时,我该如何应用这个原则,因为实现 class 是一个特定的极端情况。
假设我有这个界面示例:
Interface Input {
Input create();
void capitalizeInput(CAPITALIZATION cap);
String getInput();
}
Class LatinInput implements Input {
String input;
Input create(String input){...}
void capitalizeInput(CAPITALIZATION cap){...}
String getInput(){...}
}
Class NumberOnlyInput implements Input {
int input;
Input create(int input){...}
void capitalizeInput(CAPITALIZATION cap){
// Needed because the interface requires it.
return;
}
String getInput(){...}
}
该接口被其他 classes 在程序中广泛使用。目前在我的程序中,我正在做类似以下的事情。
Class B {
Input input;
B(Input input){
this.input = input;
}
String doStuff(){
...
methodA();
...
methodB();
...
methodC();
...
methodA();
...
return ...;
}
private void methodA(){
...
input.transformInput(CAPITAL);
input.getInput();
}
private void methodB(){
...
input.getInput();
}
private void methodC(){
...
input.transformInput();
}
}
并且被C类调用;
Class C {
void doStuff() {
List<A> list = new Arraylist<>();
list.add(LatinInput.create("hello"));
list.add(LatinInput.create("goodbye"));
list.add(NumberOnlyInput.create(12345));
for(Input input: list){
B b = new B(a);
b.doStuff();
}
}
}
我应该如何更改设计以符合 ISP,而不更改 class C,同时也不需要在运行时检查对象是否 instance of
?
Interface segregation principle:
states that no client should be forced to depend on methods it does not use.
它没有说任何关于用空主体实现方法的事情。你的classB
同时使用了capitalizeInput
和getInput
,只要是Input
中的两个方法,就不会违反接口隔离原则。在您的情况下 B
使用 NumberOnlyInput.capitalizeInput
碰巧 empy body 是此功能的有效实现。
但是,Input.create
确实违反了ISP。 B
依赖于 Input
但不使用 Input.create
- 它根本没有被调用。在这种情况下,您可以将其从界面中删除。
你仍然可以摆脱那个奇怪的空方法。由于 NumberOnlyInput
是 LatinInput
的特例,您可以重复使用 class:
class NumberOnlyInput {
static Input create(int input) {
return new LatinInput(String.valueOf(input));
}
}
它可能不太清晰或不太高效 - 这可能就是为什么首先创建数字的特殊情况。