介面切割原則
Prerequisites:
介面切割原則
英文是Interface Segregation Principle
我覺得稱為介面最小化原則比較適合。
下圖中有Interface1,ImplementA與ImplementA去實作Interface1
A與B類別會用到Interface1
Interface1
1
2
3
4
5
6
public interface Interface1 {
public void method1();
public void method2();
public void method3();
public void method4();
}
ImplementA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ImplementA implements Interface1 {
@Override
public void method1() {
}
@Override
public void method2() {
}
@Override
public void method3() {
}
@Override
public void method4() {
}
}
ImplementB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ImplementB implements Interface1 {
@Override
public void method1() {
}
@Override
public void method2() {
}
@Override
public void method3() {
}
@Override
public void method4() {
}
}
A類別用到Interface1,呼叫method1與method2與method3。
1
2
3
4
5
6
7
8
9
10
11
12
public class A {
public void call1(Interface1 interface1) {
interface1.method1();
}
public void call2(Interface1 interface1) {
interface1.method2();
}
public void call3(Interface1 interface1) {
interface1.method3();
}
}
B類別用到Interfac1,呼叫method3與method4
1
2
3
4
5
6
7
8
public class B {
public void call3(Interface1 interface1) {
interface1.method3();
}
public void call4(Interface1 interface1) {
interface1.method4();
}
}
main主程式
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {
public static void main(String[] args) {
A a = new A();
B b = new B();
ImplementA implementA = new ImplementA();
ImplementB implementB = new ImplementB();
a.call1(implementA);
a.call2(implementA);
a.call3(implementA);
b.call3(implementB);
b.call4(implementB);
}
}
問題
以上程式碼是類別圖的實作,但會出現以下問題
ImplementA與ImplementB實作Interface1全部方法
Interface1的方法,A類別B類別不會全部用到
A類別不會用到ImplementA實作的method4()。
B類別不會用到ImplementB實作的method1()與method2()不會用到。
改善方法
A類別會用到method1(),method2(),method3()
B類別會用到method3(),method4()
- A類別,B類別都會用到method3(),把method3()抽出來成為一個介面。
- A類別還會用到method1()與method2(),把這二個抽出來成為一個介面。
- B類別還會用到method4(),把method4()抽出來作為單獨的介面。
切割過的介面類別圖如下:
ImplementA實作Interface12與Interface3
ImplementB實作Interface4與Interface3
以下的類別圖加上A類別與B類別:
- A類別會用到Interface12與Interface3
- B類別會用到Interface4與Interface3
切割過的Interface程式碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
public interface Interface12 {
public void method1();
public void method2();
}
public interface Interface3 {
public void method3();
}
public interface Interface4 {
public void method4();
}
ImplementA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ImplementA implements Interface12, Interface3 {
@Override
public void method1() {
}
@Override
public void method2() {
}
@Override
public void method3() {
}
}
ImplementB
1
2
3
4
5
6
7
8
9
10
11
12
public class ImplementB implements Interface3, Interface4 {
@Override
public void method3() {
}
@Override
public void method4() {
}
}
A類別
1
2
3
4
5
6
7
8
9
10
11
public class A {
public void call1(Interface12 interface12) {
interface12.method1();
}
public void call2(Interface12 interface12) {
interface12.method2();
}
public void call3(Interface3 interface3) {
interface3.method3();
}
}
B類別
1
2
3
4
5
6
7
8
public class B {
public void call3(Interface3 interface3) {
interface3.method3();
}
public void call4(Interface4 interface4) {
interface4.method4();
}
}
main主程式
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {
public static void main(String[] args) {
A a = new A();
B b = new B();
ImplementA implementA = new ImplementA();
ImplementB implementB = new ImplementB();
a.call1(implementA);
a.call2(implementA);
a.call3(implementA);
b.call3(implementB);
b.call4(implementB);
}
}