define

Adapter patterns, also known as transformer patterns, change the interface of one class to the interface that the client expects, so that two classes that could not work in the past because of interface mismatch can work together. In the case of not changing the original code, the original function of a transformation, extension, so that the original function can meet the new requirements.

Three types of writing

  1. The class adapter
  2. Object adapter
  3. Interface adapter

1. Class adapters (the roles existing in the system are translated into what the target needs)

Scenario description: the voltage is 220V. The demand is that it can output 5V voltage and 220V voltage at the same time. The 220V voltage needs to be converted into 5V voltage output, so the voltage of 5V should be increased without changing the 220V voltage class. New 5V voltage interface, new adapter class, adapter class inheritance 220V voltage, 5V voltage interface. In the adapter class processing 220V conversion 5V logic, the final implementation can output 5V voltage.Copy the code

Public class AC220 {public int outputac220 (){int output = 220; System.out.println(" output voltage "+ output + "V"); return output; }}Copy the code
Public interface DC5 {int output5V (); }Copy the code
/** * class Adaptor class */ Public Class PowerAdapter extends AC220 implements DC5 {@override public int output5V() {int adapterInput = super.outputAC220V(); int adapterOutput = adapterInput / 44; Println (" use Adapter input AC"+ adapterInput +"V", output AC"+adapterOutput+"V"); return adapterOutput; }}Copy the code
/** * Test */ public class Test {public static void main(String[] args) {DC5 Adapter = new PowerAdapter(); adapter.output5V(); }}Copy the code

2. Object adapters (the roles existing in the system are converted to what the target needs)

Scenario description: the 220V voltage needs to be converted to 5V voltage. Only 5V voltage is required, and no 22V voltage is retained. New 5V voltage interface, new adapter class construction method input voltage of 220V, DC5V interface, in the implementation of output5V() method inside the implementation of the LOGIC of 220V to 5V. The client calls the adapter with only DC5V methods.Copy the code

public class AC220 { public int outputAC220V(){ int output = 220; System.out.println(" output voltage "+ output + "V"); return output; }}Copy the code
Public interface DC5 {int output5V(); }Copy the code
Public class PowerAdapter implements DC5 {private AC220 implements DC5; private AC220 implements DC5; private AC220 implements DC5; public PowerAdapter(AC220 ac220) { this.ac220 = ac220; } @Override public int output5V() { int adapterInput = ac220.outputAC220V(); int adapterOutput = adapterInput / 44; Println (" use Adapter input AC"+ adapterInput +"V", output AC"+adapterOutput+"V"); return adapterOutput; }}Copy the code
public class Test { public static void main(String[] args) { DC5 adapter = new PowerAdapter(new AC220()); adapter.output5V(); }}Copy the code

3. Interface adapter

Interface adapterCopy the code

Public class AC220 {public int outputac220 (){int output = 220; System.out.println(" output voltage "+ output + "V"); return output; }}Copy the code
public interface DC {

    int output5V();
    int output12V();
    int output24V();
    int output36();
}
Copy the code
Public class PowerAdapter implements DC {private AC220 AC220; public class PowerAdapter implements DC {private AC220 AC220; public PowerAdapter(AC220 ac220) { this.ac220 = ac220; } @Override public int output5V() { int output = ac220.outputAC220V() / 44; return output; } @Override public int output12V() { int output = ac220.outputAC220V() / 18; return output; } @Override public int output24V() { int output = ac220.outputAC220V() / 9; return output; } @Override public int output36() { int output = ac220.outputAC220V() / 6; return output; }}Copy the code
public class Test { public static void main(String[] args) { DC adapter = new PowerAdapter(new AC220()); adapter.output5V(); }}Copy the code

4. Login example

Background: The original project only registration, login account, the existing registration and login method is very stable, now need to add a third party login, the bottom or call the old registration and login method.Copy the code

Methods a

Disadvantages: it is not easy to expand again, at this time if the increase, microblogging record... And so on. You need to change the interface, change the adapter. Inconsistent with the open closed principle.Copy the code

public class ResultMsg { private int code; private String msg; private Object data; public ResultMsg(int code, String msg, Object data) { this.code = code; this.msg = msg; this.data = data; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Object getData() { return data; } public void setData(Object data) { this.data = data; }}Copy the code
/** * @param username * @param password * @return */ public ResultMsg Regist (String username,String password) {return new ResultMsg(200," registered successfully ",new Member()); } /** * @param username * @param password * @return */ public ResultMsg login(String username,String password) { Return new ResultMsg(200," login succeeded ",new Member()); }}Copy the code
/** * target interface */ public interface IPassportForOther {ResultMsg loginForQQ(String openId); ResultMsg loginForWechat(String openId); ResultMsg loginForToken(String token); ResultMsg loginForTelphone(String phone,String code); }Copy the code
Public Class PassportForOtherAdapter extends PassportService implements IPassportForOther {@override Public ResultMsg loginForQQ(String openId) {return loginForRegist(openId,null); // return loginForRegist(openId,null); // return loginForRegist(openId,null); } @Override public ResultMsg loginForWechat(String openId) { return loginForRegist(openId,null); } @Override public ResultMsg loginForToken(String token) { return loginForRegist(token,null); } @override public ResultMsg loginForTelphone(String phone, String code) {// TODO Return loginForRegist(phone,null); } /** * You can't use a password to log in to a third party. ** * you can't use a password to log in to a third party. ** ** You can't use a password to log in. The password is invalid. * @param username * @param password * @return */ private ResultMsg loginForRegist(String username,String password) {// Convention, password is empty, use the built-in login password, and if(null == password) {password = "THIRD_EMPTY"; } super.regist(username,password); return super.login(username,password); }}Copy the code
Public class Test {public static void main(String[] args) {PassportForOtherAdapter Adapter = new PassportForOtherAdapter(); adapter.login("admin","123456"); adapter.loginForQQ("sdfgsfghs"); LoginForWechat (" falkjKjnkvf "); // The unique development ID provided by QQ is adapter.loginforwechat ("falkjkjnkvf"); // The unique open ID provided by wechat}}Copy the code

The advanced

The implementation method of mode one does not conform to the open closed principle. Advanced version of the idea: with two adapters, a master adapter, play the role of scheduling, each login mode to write an adapter, add login mode, add adapter class, do not need to change the original code, just add class.

/** * @param username * @param password * @return */ public ResultMsg Regist (String username,String password) {return new ResultMsg(200," registered successfully ",new Member()); } /** * @param username * @param password * @return */ public ResultMsg login(String username,String password) { Return new ResultMsg(200," login succeeded ",new Member()); }}Copy the code
public class ResultMsg { private int code; private String msg; private Object data; public ResultMsg(int code, String msg, Object data) { this.code = code; this.msg = msg; this.data = data; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Object getData() { return data; } public void setData(Object data) { this.data = data; }}Copy the code
/** * Logon adapter interface */ public interface ILoginAdapter {// Whether the adapter matches Boolean support(Object Object); // Call the third-party SDK to get the login token String Token (); }Copy the code
public interface IPassportForOther {
    ResultMsg loginForOther();
}
Copy the code
public class LoginForQQAdapter implements ILoginAdapter{ @Override public boolean support(Object object) { return false;  } @override public String token() {system.out.println (" send HTTP request "); Println ("QQ login, QQ return unique ID->"); String username = "admin"; return username; }}Copy the code
Public Class PassportForOtherAdapter extends PassportService implements IPassportForOther{private ILoginAdapter loginAdapter; public PassportForOtherAdapter(ILoginAdapter loginAdapter) { this.loginAdapter = loginAdapter; } /** * Third party login * @return */ @override public ResultMsg loginForOther() {return loginForRegist(loginAdapter.token(),null); } /** * you can't use a password to log in to a third-party login, so you can set a default THIRD_EMPTY password for a third-party login. * If a user cannot set the password, a message is displayed indicating that the password is invalid. * * @param username * @param password * @return */ protected ResultMsg loginForRegist(String username, String password) { if (null == password) { password = "THIRD_EMPTY"; } super.regist(username, password); return super.login(username, password); }}Copy the code
public class Test {

    public static void main(String[] args) {
        IPassportForOther adapter = new PassportForOtherAdapter(new LoginForQQAdapter());
        adapter.loginForOther();
    }
}
Copy the code