Adapter
使用時機
你想要使用一個已經存在的類別(且/或者包含這個類別的子類別),雖然這個類別在功能上符合你的需求, 但是它的介面和你所期待的並不相容。
你想要設計可被重複使用的類別,希望這個類別可以跟不相關或是未知的其他類別一起合作。也就是說,
你希望類別之間既使介面互不相容也可以一起合作。
from: Structural Patterns要解決什麼問題(上)?
from: Adapter Pattern Tutorial with Java Examples
Example
Adaptee
public interface Xpay {
public String getCreditCardNo();
public String getCustomerName();
public String getCardExpMonth();
public String getCardExpYear();
public Short getCardCVVNo();
public Double getAmount();
public void setCreditCardNo(String creditCardNo);
public void setCustomerName(String customerName);
public void setCardExpMonth(String cardExpMonth);
public void setCardExpYear(String cardExpYear);
public void setCardCVVNo(Short cardCVVNo);
public void setAmount(Double amount);
}
public class XpayImpl implements Xpay{
private String creditCardNo;
private String customerName;
private String cardExpMonth;
private String cardExpYear;
private Short cardCVVNo;
private Double amount;
@Override
public String getCreditCardNo() {
return creditCardNo;
}
@Override
public String getCustomerName() {
return customerName;
}
@Override
public String getCardExpMonth() {
return cardExpMonth;
}
@Override
public String getCardExpYear() {
return cardExpYear;
}
@Override
public Short getCardCVVNo() {
return cardCVVNo;
}
@Override
public Double getAmount() {
return amount;
}
@Override
public void setCreditCardNo(String creditCardNo) {
this.creditCardNo = creditCardNo;
}
@Override
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
@Override
public void setCardExpMonth(String cardExpMonth) {
this.cardExpMonth = cardExpMonth;
}
@Override
public void setCardExpYear(String cardExpYear) {
this.cardExpYear = cardExpYear;
}
@Override
public void setCardCVVNo(Short cardCVVNo) {
this.cardCVVNo = cardCVVNo;
}
@Override
public void setAmount(Double amount) {
this.amount = amount;
}
}
Target
public interface PayD {
public String getCustCardNo();
public String getCardOwnerName();
public String getCardExpMonthDate();
public Integer getCVVNo();
public Double getTotalAmount();
public void setCustCardNo(String custCardNo);
public void setCardOwnerName(String cardOwnerName);
public void setCardExpMonthDate(String cardExpMonthDate);
public void setCVVNo(Integer cVVNo);
public void setTotalAmount(Double totalAmount);
}
Adapter
public class XpayToPayDAdapter implements PayD{
private String custCardNo;
private String cardOwnerName;
private String cardExpMonthDate;
private Integer cVVNo;
private Double totalAmount;
private final Xpay xpay;
public XpayToPayDAdapter(Xpay xpay){
this.xpay = xpay;
setProp();
}
@Override
public String getCustCardNo() {
return custCardNo;
}
@Override
public String getCardOwnerName() {
return cardOwnerName;
}
@Override
public String getCardExpMonthDate() {
return cardExpMonthDate;
}
@Override
public Integer getCVVNo() {
return cVVNo;
}
@Override
public Double getTotalAmount() {
return totalAmount;
}
@Override
public void setCustCardNo(String custCardNo) {
this.custCardNo = custCardNo;
}
@Override
public void setCardOwnerName(String cardOwnerName) {
this.cardOwnerName = cardOwnerName;
}
@Override
public void setCardExpMonthDate(String cardExpMonthDate) {
this.cardExpMonthDate = cardExpMonthDate;
}
@Override
public void setCVVNo(Integer cVVNo) {
this.cVVNo = cVVNo;
}
@Override
public void setTotalAmount(Double totalAmount) {
this.totalAmount = totalAmount;
}
private void setProp(){
setCardOwnerName(this.xpay.getCustomerName());
setCustCardNo(this.xpay.getCreditCardNo());
setCardExpMonthDate(this.xpay.getCardExpMonth()+"/"+this.xpay.getCardExpYear());
setCVVNo(this.xpay.getCardCVVNo().intValue());
setTotalAmount(this.xpay.getAmount());
}
}
Client
public class RunAdapterExample {
public static void main(String[] args) {
// Object for Xpay
Xpay xpay = new XpayImpl();
xpay.setCreditCardNo("4789565874102365");
xpay.setCustomerName("Max Warner");
xpay.setCardExpMonth("09");
xpay.setCardExpYear("25");
xpay.setCardCVVNo((short)235);
xpay.setAmount(2565.23);
PayD payD = new XpayToPayDAdapter(xpay);
testPayD(payD);
}
private static void testPayD(PayD payD){
System.out.println(payD.getCardOwnerName());
System.out.println(payD.getCustCardNo());
System.out.println(payD.getCardExpMonthDate());
System.out.println(payD.getCVVNo());
System.out.println(payD.getTotalAmount());
}
}
from: Adapter Design Pattern