设计模式学习笔记——适配器(Adapter)模式
@(设计模式)[设计模式, 适配器模式, adapter, 适配器]
基本介绍
适配器模式一般用于将已实现的功能,通过一个转换器,转换为所需要的接口。
例如,变压器就是一个很好的例子,在我国,民用用电一般是220V交流电,但是手机充电一般是5V或者9V的直流电,这时候就可以通过一个叫做“电源适配器”的东西,将220V交流电转换为5V或者9V的直流电。
适配器还有个别名,Wrapper(包装器)。其意思也很好理解,适配器不就是把已有功能重新包装了一次吗?
适配器案例
类适配器模式
基于继承的适配器模式。
类图
Banner类
package com.pc.adapter.example.inheritor;
/**
* 旗帜类(实际情况)
* Created by switch on 17/1/21.
*/
public class Banner {
// 标语
private String slogan;
/**
* 传入标语构造旗帜对象
*
* @param slogan 标语
*/
public Banner(String slogan) {
this.slogan = slogan;
}
/**
* 弱化旗帜标语,并展示
*/
public void showWithParen() {
System.out.println("(" + slogan + ")");
}
/**
* 强化旗帜标语,并展示
*/
public void showWithAster() {
System.out.println("*" + slogan + "*");
}
}
Print接口
package com.pc.adapter.example.inheritor;
/**
* 打印接口(需求)
* Created by switch on 17/1/21.
*/
public interface Print {
/**
* 打印弱化的字符串
*/
void printWeak();
/**
* 打印强化的字符串
*/
void printStrong();
}
PrintBanner类
package com.pc.adapter.example.inheritor;
/**
* 打印旗帜信息(转换装置)
* Created by switch on 17/1/21.
*/
public class PrintBanner extends Banner implements Print {
/**
* 传入标语构造旗帜对象
*
* @param slogan 标语
*/
public PrintBanner(String slogan) {
super(slogan);
}
@Override
public void printWeak() {
showWithParen();
}
@Override
public void printStrong() {
showWithAster();
}
}
测试类
package com.pc.adapter.example.inheritor.test;
import com.pc.adapter.example.inheritor.Print;
import com.pc.adapter.example.inheritor.PrintBanner;
import org.junit.Test;
/**
* 旗帜适配器测试——适配器采用类适配器模式
* 也就是基于继承的适配器模式
* Created by switch on 17/1/21.
*/
public class InheritorBannerAdapterTest {
@Test
public void testInheritorBannerAdapter() {
Print print = new PrintBanner("我们的口号是,没有蛀牙!");
print.printWeak();
print.printStrong();
}
}
运行结果
(我们的口号是,没有蛀牙!)
*我们的口号是,没有蛀牙!*
对象适配器模式
基于委托的适配器模式。
类图
Banner类
package com.pc.adapter.example.delegation;
/**
* 旗帜类(实际情况)
* Created by switch on 17/1/21.
*/
public class Banner {
// 标语
private String slogan;
/**
* 传入标语构造旗帜对象
*
* @param slogan 标语
*/
public Banner(String slogan) {
this.slogan = slogan;
}
/**
* 弱化旗帜标语,并展示
*/
public void showWithParen() {
System.out.println("(" + slogan + ")");
}
/**
* 强化旗帜标语,并展示
*/
public void showWithAster() {
System.out.println("*" + slogan + "*");
}
}
Print类
package com.pc.adapter.example.delegation;
/**
* 打印类(需求)
* Created by switch on 17/1/21.
*/
public abstract class Print {
/**
* 打印弱化的字符串
*/
public abstract void printWeak();
/**
* 打印强化的字符串
*/
public abstract void printStrong();
}
PrintBanner类
package com.pc.adapter.example.delegation;
/**
* 打印旗帜信息(转换装置)
* Created by switch on 17/1/21.
*/
public class PrintBanner extends Print {
// 旗帜对象
private Banner banner;
public PrintBanner(String slogan) {
banner = new Banner(slogan);
}
@Override
public void printWeak() {
banner.showWithParen();
}
@Override
public void printStrong() {
banner.showWithAster();
}
}
测试类
package com.pc.adapter.example.delegation.test;
import com.pc.adapter.example.delegation.Print;
import com.pc.adapter.example.delegation.PrintBanner;
import org.junit.Test;
/**
* 旗帜适配器测试——适配器采用对象适配器模式
* 也就是基于委托的适配器模式
* Created by switch on 17/1/21.
*/
public class DelegationBannerAdapterTest {
@Test
public void testInheritorBannerAdapter() {
Print print = new PrintBanner("我们的口号是,没有蛀牙!");
print.printWeak();
print.printStrong();
}
}
运行结果
(我们的口号是,没有蛀牙!)
*我们的口号是,没有蛀牙!*
适配器模式中的角色
Target (对象)
该角色负责定义所需的方法。在案例中,由Print
接口(使用继承时)和Print
类(使用委托时)扮演此角色。
Client(请求者)
该角色负责使用Target
角色所定义的方法进行具体处理。在案例中,由测试类扮演此角色。
Adaptee(被适配)
注意不是Adapt-er
(适配)角色,而是Adapt-ee
(被适配)角色。Adaptee
是一个持有既定方法的角色。在案例中,由Banner
类扮演此角色。
如果Adaptee
角色中的方法与Target
角色的方法相同,就不需要接下来的Adapter
角色了。
Adapter(适配)
Adapter
模式的主人公。使用Adaptee
角色的方法来满足Target
角色的需求,这是Adapter
模式的目的, 也是 Adapter
角色的作用。在案例中,由PrintBanner
类扮演这个角色。在类适配器模式中,Adapter
角色通过继承来使用Adaptee
角色,而在 对象适配器模式中, Adapter
角色通过委托来使用Adaptee
角色。
类图
类适配器模式的类图
对象适配器模式的类图
GitHub:DesignPatternStudy
——————参考《图解设计模式》