定义
将抽象部分与它的具体实现部分分离,使它们都可以独立地变化。
通过组合的方式建立两个类之间的联系,而不是继承。
类型
结构型
适用场景
①、抽象和具体实现之间增加更多的灵活性。
②、一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。
③、不希望使用继承,或因为多层继承导致系统类的个数剧增。
优缺点
优点:
①、分离抽象部分及其具体实现部分。
②、提高了系统的可扩展性。
③、符合开闭原则。
④、符合合成复用原则。
缺点:
①、增加了系统的理解与设计难度。
②、需要正确地识别出系统中两个独立变化的维度。
代码实现
案例:银行有工商银行,农业银行,招商银行等,当然每个银行还提供了不同的储蓄业务,例如:活期和定期。如果想办理不同的储蓄业务,首先得有一个账号。
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