1. Introduction to adapter mode
Adapter mode: Converts a class's trans-interface to another interface that the client wants. The adapter mode enables which classes that were previously unable to work due to incompatible interfaces to work to be compatible.
Scenarios: codec, drag-and-drop three charging heads, HDMI to VGA
Implication of Spring: Spring AOP module supports BeforeAdvice, AfterAdvice, ThrowsAdvice notification types by virtue of adapter mode, which allows the framework to allow users to add any notification type they want to support to the framework.Defined by the Spring AOP module, they are subtypes of Advice defined by the AOP federation.Basic adapters end with adapters in spring
Take a look at one of the adapter modes. Object adapter uml diagram
Adapter mode.png
You can see that the Adapter adapter contains a reference to the Adeptee adapter, which converts the adaptee adapter into a target interface and implements the interface conversion problem.
2. Adapter mode classification
There are three categories:
- Class adapters (implemented by referencing adapters in combination)
- Object adapters (implemented by inheriting adapters)
- Interface adapters (adapting through abstract classes)
The first two are slightly different in implementation, and the third interface adapter has the same effect.
3. Instance explanation of adapter
-
(1) Class adapter mode
Principle: Adapter functionality is achieved through inheritance.
In this case, we can define an adapter p to relay. This adapter P implements Interface A we access so that we can continueAccessing the current method in Interface A (although it is not currently our dish) and then inheriting the implementation class of Interface B, so that we can access the method of Interface B in Adapter P, we now refer directly to the appropriate method in B in the Interface A method in Adapter P, thus completing a simple class adapter.
The following example is:By converting a normal login interface to a WeChat login interface
Login Return Status Class
/** * @Project: spring * @description: Class of results returned by login * @author: sunkang * @create: 2018-09-05 20:55 * @ModificationHistory who when What **/ public class ResultMsg { private String code; private String msg; private Object data; public ResultMsg(String code, String msg, Object data) { this.code = code; this.msg = msg; this.data = data; } public String getCode() { return code; } public void setCode(String 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; } }
Common Login Interface
/** * @Project: spring * @description: Login Interface Business * @author: sunkang * @create: 2018-09-05 20:51 * @ModificationHistory who when What **/ public interface ISiginSerevice { ResultMsg login(String username,String password); }
Specific implementation of login
* @Description: * @Param: Specific implementation of login * @return: * @Author: sunkang * @Date: 2018/9/5 */ public class SiginService implements ISiginSerevice { /** * Login Method * @param username * @param password * @return */ public ResultMsg login(String username,String password){ return new ResultMsg("200","Login Successful",new Object()); } }
Log on through the WeChat interface
/** * @Project: spring * @description: Log on through the WeChat interface * @author: sunkang * @create: 2018-09-05 20:58 * @ModificationHistory who when What **/ public interface ISiginForWebChat { /** * Sign in via WeChat * @param openId * @return */ ResultMsg loginForWechat(String openId); }
Class adapter (adapts the original login method to the WeChat login interface)
/** * @Project: spring * @description: Class adapter target interface is ISiginForWebChat, but adapter's interface is ISiginService * @author: sunkang * @create: 2018-09-05 21:29 * @ModificationHistory who when What **/ public class ClassSiginForWebChatAdapter extends SiginService implements ISiginForWebChat{ @Override public ResultMsg loginForWechat(String openId) { return login(openId,null); } }
- (2) Object adapter mode
Principle: Adapter functionality is achieved through combination.
Because it's simpler, it should be clearer, and the code is as follows
/** * @Project: spring * @description: Object adapters are implemented by default through composition * @author: sunkang * @create: 2018-09-05 21:06 * @ModificationHistory who when What **/ public class ObjectSiginForWebChatAdapter implements ISiginForWebChat { private ISiginSerevice siginSerevice; public ObjectSiginForWebChatAdapter(ISiginSerevice siginSerevice) { this.siginSerevice = siginSerevice; } @Override public ResultMsg loginForWechat(String openId) { return siginSerevice.login(openId,null); } }
-
(3) Interface adapter mode
Principle: Adaptation is implemented through abstract classes, which are slightly different from the adapters described above.
When there is an interface where there are more than N methods defined, and now we only want to use one or more of them. If we implement the interface directly, then we need to implement all of them, even if we just leave the unnecessary methods blank (just write a pair of braces, not specific)Method implementations) can also cause this class to become bloated and inconvenient to invoke, so we can use an abstract class as the middleware, the adapter, to implement the interface with this abstract class, and all methods in the abstract class are empty, so we are creating inherited classes of the abstract class and overriding what we needThe methods used are sufficient.
For example, login now supports third-party interfaces, such as qq login, WeChat login, mobile phone number login and authentication number login, but some implementation classes are not generic to these methods, you can use an abstract class to implement all methods of the interface, as a default implementation, and then implement class inheritance specificallyDraw > Image class, override which method to use
Interface for third party login
/** * @Project: spring * @description: Interface for third party login * @author: sunkang * @create: 2018-09-05 21:41 * @ModificationHistory who when What **/ public interface ISiginForThirdService { /** * Log in via qq q * @param openId * @return */ ResultMsg loginForQQ(String openId); /** * Sign in via WeChat * @param openId * @return */ ResultMsg loginForWechat(String openId); /** * Log in with your mobile number and authentication number * @param telphone * @param code * @return */ ResultMsg loginForTelphone(String telphone,String code); }
Abstract adapter
/** * @Project: spring * @description: Abstract adapter Because there are too many interfaces, an adapter for an abstract class is used to implement by default * @author: sunkang * @create: 2018-09-05 21:43 * @ModificationHistory who when What **/ public abstract class SiginForThirdAdapter implements ISiginForThirdService { @Override public ResultMsg loginForQQ(String openId) { return new ResultMsg("200","qq Login Successful",new Object()); } @Override public ResultMsg loginForWechat(String openId) { return new ResultMsg("200","WeChat logged in successfully",new Object()); } @Override public ResultMsg loginForTelphone(String telphone, String code) { return new ResultMsg("200","Mobile Logon Successful",new Object()); } }
Logging in with a phone number and dynamic password requires only rewriting the corresponding method interface
/** * @Project: spring * @description: Just sign in with a phone number * @author: sunkang * @create: 2018-09-05 21:44 * @ModificationHistory who when What **/ public class LoginForTelphoneAdapter extends SiginForThirdAdapter { public ResultMsg loginForTelphone(String telphone, String code) { System.out.println("Log on by phone number"); ResultMsg msg = new ResultMsg("200","qq Login Successful",new Object()); System.out.println("The result of login is"+msg.getMsg()); return msg; } }
Three Ways of Test Cases
/** * @Project: spring * @description: Test cases implemented in three ways * @author: sunkang * @create: 2018-09-05 21:17 * @ModificationHistory who when What **/ public class AdapterTest { public static void main(String[] args) { //An adapted class is required to make ISiginSerevice ISiginForWebChat ISiginSerevice siginSerevice = new SiginService(); ISiginForWebChat siginForThreadService = new ObjectSiginForWebChatAdapter(siginSerevice); //Object adapter, which passes an adapted class in a combined manner ResultMsg resultMsg = siginForThreadService.loginForWechat("1231321ffasfasffad"); System.out.println(resultMsg.getMsg()); //Class adapter, implemented by inheritance ResultMsg msg = new ClassSiginForWebChatAdapter().loginForWechat("1231321ffasfasffad"); System.out.println(msg.getMsg()); //Interface adapter, which implements an abstract adapter //But there are so many methods in an interface that we have to implement and implement all of them when we want to use it. We can use abstract classes to implement interfaces //The method is not implemented (just empty), and then we inherit this abstract class to implement it by overriding the method we want to use.This abstract class is the adapter ISiginForThirdService siginForWebChat = new LoginForTelphoneAdapter(); ResultMsg telPoneMsg = siginForWebChat.loginForTelphone("13588304966","1234"); System.out.println(telPoneMsg.getMsg()); } }
4. Adapter mode scenarios
Class adapters are used in the same scenario as object adapters, but only slightly differently. They are mainly used in the following scenarios:
- If you want to use a class that already exists, but it does not conform to the existing interface specifications, and you cannot access it directly, you can create an adapter to access the methods in that class indirectly.
- We have a class that we want to design to be reusable (accessible in multiple places), and we can create adapters to fit this class into other classes that do not provide the appropriate interface.
The two scenarios above describe a problem from two perspectives: the method to be accessed is not in the appropriate interface, one from the interface (accessed) and the other from the access (active access).
Interface adapter usage scenarios:
- You want to use one or some of the methods in the interface, but there are too many methods in the interface. To use this, you must implement the interface and implement all the methods in it. You can use abstract classes to implement the interface, not methods (just empty). Then we inherit this abstract class to override the intended party.Method is implemented.This abstract class is the adapter.