适配器模式与桥接模式
适配器模式
适配器模式(Adapter Pattern),它的目的是将一个类的接口编程客户端所期望的另一种接口,从而是原本接口不匹配而导致无法在一起工作的两个类能一起工作,属于结构型设计模式。
适配器模式的角色:
目标角色(Target):也就是我们期望的接口
源角色(Adaptee):存在系统中,内容满足客户需求(需转换),但是接口不匹配的接口实例
适配器(Adapter): 将源角色(Adaptee)转换成目标角色(Target)的类实例
适配器模式有3中方式: 类适配器 对象适配器 接口适配器
//类适配器,适配器直接继承源角色,实现目标角色实现转换
public interface DC5output {
public int output();
}
public class DC220output {
public int output220(){
System.out.println("调用输出220v");
return 220;
}
}
public class PowerAdapter extends DC220output implements DC5output{
public int output() {
System.out.println("将220v转换为5v");
int i = super.output220();
int target = i/44;
System.out.println("输入电压:" + i +"v,输出电压:" + target + "v");
return target;
}
public static void main(String[] args) {
PowerAdapter powerAdapter = new PowerAdapter();
powerAdapter.output();
}
}
//对象适配器,实现目标适配器 并持有源目标的对象引用
public interface DC5output {
public int output();
}
public class DC220output {
public int output220(){
System.out.println("调用输出220v");
return 220;
}
}
public class PowerAdapter implements DC5output{
private DC220output dc220output;
public PowerAdapter(DC220output dc220output) {
this.dc220output = dc220output;
}
public int output() {
int i = dc220output.output220();
int target = i/44;
System.out.println("输入电压:" + i + "v,输出电压:" + target + "v");
return target;
}
public static void main(String[] args) {
DC220output dc220output = new DC220output();
PowerAdapter powerAdapter = new PowerAdapter(dc220output);
powerAdapter.output();
}
}
//接口适配主要是为了解决目标接口过多,直接实现需要实现大量空方法,通过中间适配对象去实现目标接口,减少空实现
public interface DC {
int output5V();
int output12V();
int output24V();
int output36V();
}
public class AC220 {
public int output220V(){
int output = 220;
System.out.println("输出电压:" + output + "V");
return output;
}
}
public class PowerAdapter implements DC{
private AC220 ac220;
public PowerAdapter(AC220 ac220) {
this.ac220 = ac220;
}
public int output5V() {
int adapterInput = ac220.output220V();
int adapterOutput = adapterInput/44;
System.out.println("输入电压:" + adapterInput + "V,输出电压:" + adapterOutput + "V");
return adapterOutput;
}
/**
* 提供默认实现
* @return
*/
public int output12V() {
return 0;
}
public int output24V() {
return 0;
}
public int output36V() {
return 0;
}
}
源码中适配器模式的使用
源码中还有适配器的一种特殊实现,看起来更像是一种策略模式,但是他注重的为了匹配现有的功能,而策略模式是注重的是根据传入条件选择一种方式实现目标。所以说设计模式不是单独存在的,要灵活对待。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
try {
try {
...
try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
//传入的mappedHandler.getHandler()类型丢失了是一个Object类型
//系统只知道它是几种类型之一,如果直接用instance判断,代码耦合严重
//因此为可能出现的所有类型提供一个适配器,并缓存到集合中,迭代通过适配器的support方法去判断是否匹配,然后通过适配器的handler方法,调用原有mappedHandler.getHandler()原始对象的handler方法
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
...
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
...
}
public interface HandlerAdapter {
boolean supports(Object handler);
@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
long getLastModified(HttpServletRequest request, Object handler);
}
public class HttpRequestHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpRequestHandler);
}
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
((HttpRequestHandler) handler).handleRequest(request, response);
return null;
}
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
}
}

由于在程序掉用过程中Handler的类型丢失了,得到的Object对象无法直接调用方法,但是可以确定是几种handler具体实现之一,如果直接使用instance去if判断,代码臃肿,为了匹配原有功能,使用适配器,匹配上了就将原始类型还原在进行调用。
适配器优缺点
优点:
1.提高程序复用性,现有类复用但不需要改变
2.目标类和适配器类解耦,提高扩展性
缺点:
1.代码复杂程度变高,编写的难度大
2.降低代码可读性
桥接模式(Bridge Pattern)
桥接模式主要目的是通过组合的方式建立两个类之间的关系,而不是继承。桥接模式核心在于解耦抽象和实现。
桥接模式的角色
抽象(Abstraction): 该类持有一个实现角色的引用,抽象角色的方法需要去调用实现角色的实现。抽象角色一般是抽象类。
修正对象(RefinedAbstraction): Abstraction的实现,是关键的桥接对象,通过它完成抽象角色和实现类的关联
实现(Implementor):具体实现的操作定义,提供给Abstraction使用,该类一般为接口或者抽象类
具体实现(ConcreteImplementor) : Implementor 的具体实现

//抽象对象
public class Abstraction {
protected Implementor implemntor;
public Abstraction (Implementor implementor) {
this.implemntor = implementor;
}
public void operation(){
//执行抽象类的逻辑
//抽象方法掉用具体实现方法
this.implemntor.operationImpl();
//执行抽象类的逻辑
}
}
//操作对象
public interface Implementor {
void operationImpl();
}
//具体实现
public class ConcreteImplementorA implements Implementor{
public void operationImpl() {
System.out.println("A实现");
}
}
public class ConcreteImplementorB implements Implementor{
public void operationImpl() {
System.out.println("B实现");
}
}
//修正对象
**
* 修正对象 实现抽象对象
*/
public class RefinedAbstraction extends Abstraction{
//将具体实现和抽象对象关联
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
//可以再掉抽象对象的操作实现之前进行额外方法增强操作 before
super.operation();
//after
}
}
//测试类
public class Test {
public static void main(String[] args) {
Implementor a = new ConcreteImplementorA();
Implementor b = new ConcreteImplementorB();
//创建修正对象
Abstraction refinedAbstractionA = new RefinedAbstraction(a);
Abstraction refinedAbstractionB = new RefinedAbstraction(b);
//将抽象对象的逻辑和实现对象的逻辑通过修正对象实现了关联
refinedAbstractionA.operation();
refinedAbstractionB.operation();
}
}

浙公网安备 33010602011771号