前言
本文以Java语言为主,分析包括JDK、Spring、MyBatis、Guava、org.apache.xxx中,等一些优秀的开源代码、项目,在这些开源代码、项目中都包含了大量的设计模式,通过对它们进行分析,能够快速帮助我们学会设计模式的使用方式,由理论过渡到实践中,进而真正了解设计模式的思想,由于内容较多,所以每个设计模式单独写一篇文章,需要了解其他模式请点击对应链接跳转。
建造者模式
装饰器模式
适配器模式
策略模式
责任链模式
模板方法模式
适配器模式
Spring MVC
SpringMVC中HandlerAdapter就用到适配器模式,HandlerAdapter中定义了标准的handler方法用于处理请求。
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
SimpleServletHandlerAdapter
SimpleControllerHandlerAdapter
handler方法中分别适配了实现Controller和Servlet接口的处理方式,对外使用时只需要统一调用handle接口即可。
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
...
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
MyBatis
MyBatis中兼容了很多的日志处理框架,而然这些日志框架对应的处理级别却有所不同,所以MyBatis就统一定义了一个日志处理类,通过适配器的方式用来兼容其他的各种日志框架。
MyBatis中的定义
public interface Log {
boolean isDebugEnabled();
boolean isTraceEnabled();
void error(String s, Throwable e);
void error(String s);
void debug(String s);
void trace(String s);
void warn(String s);
}
对应其他的日志处理框架,比如Jdk14
public class Jdk14LoggingImpl implements Log {
private final Logger log;
public Jdk14LoggingImpl(String clazz) {
log = Logger.getLogger(clazz);
}
@Override
public boolean isDebugEnabled() {
return log.isLoggable(Level.FINE);
}
@Override
public boolean isTraceEnabled() {
return log.isLoggable(Level.FINER);
}
@Override
public void error(String s, Throwable e) {
log.log(Level.SEVERE, s, e);
}
@Override
public void error(String s) {
log.log(Level.SEVERE, s);
}
@Override
public void debug(String s) {
log.log(Level.FINE, s);
}
@Override
public void trace(String s) {
log.log(Level.FINER, s);
}
@Override
public void warn(String s) {
log.log(Level.WARNING, s);
}
}
JDK
Jdk中的WindowAdapter、MouseAdapter、KeyAdapter等等awt.event包下有很多类似这样的适配类,这是一种非典型的使用方法,他们分别实现了各自的XXXListener接口,但却没有对其中的逻辑进行重写,都是空现实,把具体实现逻辑交给了具体的调用者,这样做的目的主要是因为这些XXXListener接口中的方法较多,但调用者又不会每一个接口方法都会用到,所以就通过适配类来全部实现,而调用者只需要继承适配类,重写自己需要的方法即可。
public abstract class WindowAdapter
implements WindowListener, WindowStateListener, WindowFocusListener
{
/**
* Invoked when a window has been opened.
*/
public void windowOpened(WindowEvent e) {}
/**
* Invoked when a window is in the process of being closed.
* The close operation can be overridden at this point.
*/
public void windowClosing(WindowEvent e) {}
/**
* Invoked when a window has been closed.
*/
public void windowClosed(WindowEvent e) {}
/**
* Invoked when a window is iconified.
*/
public void windowIconified(WindowEvent e) {}
/**
* Invoked when a window is de-iconified.
*/
public void windowDeiconified(WindowEvent e) {}
/**
* Invoked when a window is activated.
*/
public void windowActivated(WindowEvent e) {}
/**
* Invoked when a window is de-activated.
*/
public void windowDeactivated(WindowEvent e) {}
/**
* Invoked when a window state is changed.
* @since 1.4
*/
public void windowStateChanged(WindowEvent e) {}
/**
* Invoked when the Window is set to be the focused Window, which means
* that the Window, or one of its subcomponents, will receive keyboard
* events.
*
* @since 1.4
*/
public void windowGainedFocus(WindowEvent e) {}
/**
* Invoked when the Window is no longer the focused Window, which means
* that keyboard events will no longer be delivered to the Window or any of
* its subcomponents.
*
* @since 1.4
*/
public void windowLostFocus(WindowEvent e) {}
}
调用者使用方法
public static void main(String[] args) {
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
}
});
}