定義
將抽象部分與它的具體實現部分分離,使它們都可以獨立地變化。
通過組合的方式建立兩個類之間的聯繫,而不是繼承。
類型
結構型
適用場景
①、抽象和具體實現之間增加更多的靈活性。
②、一個類存在兩個(或多個)獨立變化的維度,且這兩個(或多個)維度都需要獨立進行擴展。
③、不希望使用繼承,或因爲多層繼承導致系統類的個數劇增。
優缺點
優點:
①、分離抽象部分及其具體實現部分。
②、提高了系統的可擴展性。
③、符合開閉原則。
④、符合合成複用原則。
缺點:
①、增加了系統的理解與設計難度。
②、需要正確地識別出系統中兩個獨立變化的維度。
代碼實現
案例:銀行有工商銀行,農業銀行,招商銀行等,當然每個銀行還提供了不同的儲蓄業務,例如:活期和定期。如果想辦理不同的儲蓄業務,首先得有一個賬號。
public interface Account {
/**
* 打開賬號
*/
Account openAccount();
/**
* 顯示賬號類型
*/
void showAccountType();
}
因爲賬號的類型並不能確認,所以定義爲接口。接着分別創建不同類型的實現。
創建定期賬號
public class RegularAccount implements Account {
@Override
public Account openAccount() {
System.out.println("打開定期賬號");
return new RegularAccount();
}
@Override
public void showAccountType() {
System.out.println("這是一個定期賬號");
}
}
創建活期賬號
public class SavingAccount implements Account {
@Override
public Account openAccount() {
System.out.println("打開活期賬號");
return new SavingAccount();
}
@Override
public void showAccountType() {
System.out.println("這是一個活期賬號");
}
}
賬號有了,但是沒有支持的銀行,所以,創建銀行。
public abstract class Bank {
protected Account account;
public Bank(Account account){
this.account = account;
}
abstract Account openAccount();
}
這時,需要將賬號引入到銀行中,以這種組合的方式,讓子類來確定打開的是哪個銀行的賬號。這裏的openAccount()方法需要委託給Account中的openAccount()方法。
分別創建中國工商銀行和中國農業銀行的實現類。
public class ABCBank extends Bank {
public ABCBank(Account account) {
super(account);
}
@Override
Account openAccount() {
System.out.println("打開中國農業銀行賬號");
account.openAccount();
return account;
}
}
public class ICBCBank extends Bank {
public ICBCBank(Account account) {
super(account);
}
@Override
Account openAccount() {
System.out.println("打開中國工商銀行賬號");
account.openAccount();
return account;
}
}
接下來編寫測試類
public class MainTest {
public static void main(String[] args) {
Bank icbcBank = new ICBCBank(new RegularAccount());
Account icbcAccount = icbcBank.openAccount();
icbcAccount.showAccountType();
Bank abcBank = new ABCBank(new SavingAccount());
Account abcAccount = abcBank.openAccount();
abcAccount.showAccountType();
}
}
輸出結果:
C:\android\java\jdk1.8\bin\java.exe
打開中國工商銀行賬號
打開定期賬號
這是一個定期賬號
打開中國農業銀行賬號
打開活期賬號
這是一個活期賬號
相關源碼
1. Java封裝的JDBC中的Driver