Write in front
- Take notes on learning design patterns
- Improve flexible use of design patterns
Learning address
www.bilibili.com/video/BV1G4...
www.bilibili.com/video/BV1Np...
Reference article
c.biancheng.net/view/1317.h...
Project source code gitee.com/zhuang-kang...
10. Adapter mode
10.1 Definition and characteristics of adapter mode
The definition of the adapter mode (Adapter) is as follows: ** Convert the interface of a class into another interface that the customer wants, so that the classes that cannot work together because of the incompatibility of the interface can work together. ** Adapter mode is divided into two types: class structure mode and object structure mode. The coupling between classes in the former is higher than that in the latter.
The main advantages of this mode are as follows:
- The client can call the target interface transparently through the adapter.
- Reuse of existing classes, programmers do not need to modify the original code and reuse existing adaptor classes.
- Decoupling the target class and the adaptor class solves the problem of inconsistency in the interface between the target class and the adaptor class.
- In many business scenarios, it conforms to the opening and closing principle.
The disadvantages are:
- The adapter writing process needs to be comprehensively considered in conjunction with the business scenario, which may increase the complexity of the system.
- Increase the difficulty of code reading, reduce code readability, and excessive use of adapters will make the system code messy.
10.2 The structure and implementation of the adapter pattern
10.2.1 The structure of the adapter pattern
- Target interface: The interface expected by the current system business, which can be an abstract class or interface.
- Adaptee class: It is the component interface in the existing component library that is accessed and adapted.
- Adapter class: It is a converter that converts the adapter interface into a target interface by inheriting or referring to the object of the adapter, allowing customers to access the adapter in the format of the target interface.
10.2.2 Code Implementation
10.2.2.1 Class Adapter Mode
Voltage5V target interface
package com.zhuang.adapter.classadapter;
/**
* @Classname Voltage5V
* @Description defines direct current
* @Date 2021/3/21 14:14
* @Created by dell
*/
public interface Voltage5V {
//Define a standard charger to realize
public int output5V () ;
}
Copy code
Voltage220V
package com.zhuang.adapter.classadapter;
/**
* @Classname Voltage220V
* @Description Create AC
* @Date 2021/3/21 14:13
* @Created by dell
*/
public class Voltage220V {
public int output220V () {
System.out.println( "voltage output 220 volts" );
return 220 ;
}
}
Copy code
VoltageAdapter
package com.zhuang.adapter.classadapter;
/**
* @Classname VoltageAdapter
* @Description create a charger
* @Date 2021/3/21 14:14
* @Created by dell
*/
public class VoltageAdapter extends Voltage220V implements Voltage5V {
@Override
public int output5V () {
//Get AC 220V
int output220V = output220V();
//
Convert to 5V int output5V = output220V/ 44 ;
System.out.println( "VoltageAdapter output 5 volts" );
return output5V;
}
}
Copy code
Phone
package com.zhuang.adapter.classadapter;
/**
* @Classname Phone
* @DescriptionMobile phone class
* @Date 2021/3/21 14:15
* @Created by dell
*/
public class Phone {
public void charging (Voltage5V voltage5V) {
if (voltage5V.output5V() == 5 ) {
System.out.println( "Voltage 5V, can be charged" );
} else if (voltage5V.output5V()> 5 ) {
System.out.println( "The voltage is too large to charge" );
}
}
}
Copy code
Client
package com.zhuang.adapter.classadapter;
/**
* @Classname Client
* @Description client class
* @Date 2021/3/21 14:15
* @Created by dell
*/
public class Client {
public static void main (String[] args) {
System.out.println( "==Class adapter==" );
Phone phone = new Phone();
phone.charging( new VoltageAdapter());
}
}
Copy code
Notes and details of the class adapter pattern
- Java is a single inheritance mechanism, so the class adapter needs to inherit the adapter (Adaptee, refers to Voltage220V) class. This is a disadvantage. In addition, the target (Target, refers to Voltage5V) must be an interface, which has certain limitations.
- The methods of the adaptor Voltage220V class will be exposed in the adapter VoltageAdapter class, which also increases the cost of use. But because it inherits the adaptor Voltage220V class, it can rewrite the methods of this class according to requirements, which enhances the flexibility of the adapter VoltageAdapter class.
10.2.2.2 Object Adapter Mode
Voltage5V
package com.zhuang.adapter.objectadapter;
/**
* @Classname Voltage5V
* @Description Charging 5V
* @Date 2021/3/21 14:32
* @Created by dell
*/
public interface Voltage5V {
//Define a standard charger to realize
public int output5V () ;
}
Copy code
Voltage220V
package com.zhuang.adapter.objectadapter;
/**
* @Classname Voltage220V
* @Description output 220V class
* @Date 2021/3/21 14:32
* @Created by dell
*/
public class Voltage220V {
public int output220V () {
System.out.println( "voltage output 220 volts" );
return 220 ;
}
}
Copy code
VoltageAdapter
package com.zhuang.adapter.objectadapter;
/**
* @Classname VoltageAdapter
* @Description adapter class
* @Date 2021/3/21 14:33
* @Created by dell
*/
public class VoltageAdapter implements Voltage5V {
private Voltage220V voltage220V;
public VoltageAdapter (Voltage220V voltage220V) {
this .voltage220V = voltage220V;
}
@Override
public int output5V () {
//Get AC 220V
int output220V = voltage220V.output220V();
//
Convert to 5V int output5V = output220V/44 ;
System.out.println( "VoltageAdapter output 5V" );
return output5V;
}
}
Copy code
Phone
package com.zhuang.adapter.objectadapter;
/**
* @Classname Phone
* @DescriptionMobile phone class
* @Date 2021/3/21 14:33
* @Created by dell
*/
public class Phone {
public void charging (Voltage5V voltage5V) {
if (voltage5V.output5V() == 5 ) {
System.out.println( "The voltage is 5 volts, can be charged" );
} else if (voltage5V.output5V()> 5 ) {
System.out.println( "The voltage is too large to charge" );
}
}
}
Copy code
Client
package com.zhuang.adapter.objectadapter;
/**
* @Classname Client
* @Description object adapter test class
* @Date 2021/3/21 14:33
* @Created by dell
*/
public class Client {
public static void main (String[] args) {
System.out.println( "==Object adapter==" );
Phone phone = new Phone();
phone.charging( new VoltageAdapter( new Voltage220V()));
}
}
Copy code
Object adapter mode considerations and details
-
Object adapters and class adapters are actually the same idea, but they are implemented in different ways.
-
According to the principle of composite reuse, combination is used instead of inheritance, so it solves the limitation that VoltageAdapter must inherit Voltage220V in class adapters, and it is no longer mandatory that Voltage5V must be an interface. The use cost is lower and more flexible. Therefore, the object adapter mode is a commonly used adapter mode.
10.2.2.3 Interface adapter mode
Animation
package com.zhuang.adapter.interfaceadapter;
/**
* @Classname Animation
* @Description animation interface
* @Date 2021/3/21 14:47
* @Created by dell
*/
public interface Animation {
public void method1 () ;
public void method2 () ;
public void method3 () ;
public void method4 () ;
public void method5 () ;
}
Copy code
AnimationAdapter
package com.zhuang.adapter.interfaceadapter;
/**
* @Classname AnimationAdapter
* @Description interface adapter class
* @Date 2021/3/21 14:48
* @Created by dell
*/
public class AnimationAdapter implements Animation {
//All empty implementation
@Override
public void method1 () {
}
@Override
public void method2 () {
}
@Override
public void method3 () {
}
@Override
public void method4 () {
}
@Override
public void method5 () {
}
}
Copy code
JFrameAnimation
package com.zhuang.adapter.interfaceadapter;
/**
* @Classname JFrameAnimation
* @Description adapter subclass
* @Date 2021/3/21 14:49
* @Created by dell
*/
public class JFrameAnimation extends AnimationAdapter {
@Override
public void method1 () {
System.out.println( "method1() was called..." );
}
@Override
public void method2 () {
System.out.println( "method2() was called..." );
}
}
Copy code
Client
package com.zhuang.adapter.interfaceadapter;
/**
* @Classname Client
* @Description client class
* @Date 2021/3/21 14:50
* @Created by dell
*/
public class Client {
public static void main (String[] args) {
JFrameAnimation animation = new JFrameAnimation();
animation.method1();
animation.method2();
}
}
Copy code
10.3 SpringMVC source code analysis
Controller
package com.zhuang.adapter.springmvc;
/**
* @Classname Controller
* @Description springmvc's Controller source code
* @Date 2021/3/21 14:53
* @Created by dell
*/
//Multiple Controller implement
public interface Controller {
}
class HttpController implements Controller {
public void doHttpHandler () {
System.out.println( "http..." );
}
}
class SimpleController implements Controller {
public void doSimplerHandler () {
System.out.println( "simple..." );
}
}
class AnnotationController implements Controller {
public void doAnnotationHandler () {
System.out.println( "annotation..." );
}
}
Copy code
DispatchServlet
package com.zhuang.adapter.springmvc;
import java.util.ArrayList;
import java.util.List;
/**
* @Classname DispatchServlet
* @Description springmvc's DispatchServlet source code
* @Date 2021/3/21 14:52
* @Created by dell
*/
public class DispatchServlet {
public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();
public DispatchServlet () {
handlerAdapters.add( new AnnotationHandlerAdapter());
handlerAdapters.add( new HttpHandlerAdapter());
handlerAdapters.add( new SimpleHandlerAdapter());
}
public void doDispatch () {
//Here is the simulation of SpringMVC taking the handler object from the request,
//the adapter can get the desired Controller
HttpController controller = new HttpController();
//AnnotationController controller = new AnnotationController();
//SimpleController controller = new SimpleController();
//Get the corresponding adapter
HandlerAdapter adapter = getHandler(controller);
//Execute the corresponding controller corresponding method through the adapter
adapter.handle(controller);
}
public HandlerAdapter getHandler (Controller controller) {
//Traversal: According to the obtained controller(handler), return the corresponding adapter
for (HandlerAdapter adapter: this .handlerAdapters) {
if (adapter.supports(controller)) {
return adapter;
}
}
return null ;
}
public static void main (String[] args) {
new DispatchServlet().doDispatch();//http...
}
}
Copy code
HandlerAdapter
package com.zhuang.adapter.springmvc;
/**
* @Classname HandlerAdapter
* @Description springmvc's HandlerAdapter source code
* @Date 2021/3/21 14:53
* @Created by dell
*/
///Define an Adapter interface
public interface HandlerAdapter {
public boolean supports (Object handler) ;
public void handle (Object handler) ;
}
//Various adapter classes
class SimpleHandlerAdapter implements HandlerAdapter {
@Override
public void handle (Object handler) {
((SimpleController) handler).doSimplerHandler();
}
@Override
public boolean supports (Object handler) {
return (handler instanceof SimpleController);
}
}
class HttpHandlerAdapter implements HandlerAdapter {
@Override
public void handle (Object handler) {
((HttpController) handler).doHttpHandler();
}
@Override
public boolean supports (Object handler) {
return (handler instanceof HttpController);
}
}
class AnnotationHandlerAdapter implements HandlerAdapter {
@Override
public void handle (Object handler) {
((AnnotationController) handler).doAnnotationHandler();
}
@Override
public boolean supports (Object handler) {
return (handler instanceof AnnotationController);
}
}
Copy code
Write at the end
- If my article is useful to you, please give me some , thank you !
- If you have any questions, please point out in the comment area!