1. 写在前面
在前面的2-6小节中,我们学习了设计模式中的创建型模式。其中包括了以下几种:
-
工厂模式 FactoryMethod
:用工厂接口 & 工厂实现类的方式,将类的实例化放在子类(工厂实现类)中完成 -
原型 Sterotype
: 用已有的实例对象去创建新的对象。这里涉及到了 deep copy -
生成器 Builder
:即分步去组装。 -
单例 sinlgeton
:即一个类只能有一个实例对象,并且有一个访问节点。
整体来说,这里的创建型模式还是比较 simple 的。
下面我们来看一下结构性设计模式。
2. 结构类设计模式
所谓 结构类设计模式
是指通过各种组合,获得更灵活的性能、更稳定的表现。
尽管
java
本身提供了继承等一些列模式,用以灵活的开发。但是事实上还是不够。
因此,这里有了一系列的结构类设计模式
3. 适配器 Adapter
适配器 Adapter
的概念很好理解,生活中也经常使用。
本科的时候玩的单片机大都是 5V 直流电,而我们的电网都给的是220V交流电,因此我们需要一个充电器将二者进行转换。这个充电器就叫做 Adapter
。
在 java 的世界中也是如此,当我们有一个场景,需要将某一类对象 统一转成其他类的对象时,就需要一个 Adapter
。
4. 用法
考虑如下一个 case :
我们有一个实现 Callable
接口的 Task
类:
public class Task implements Callable<Long> {
private long num;
public Task(long num) {
this.num = num;
}
public Long call() throws Exception {
long r = 0;
for (long n = 1; n <= this.num; n++) {
r = r + n;
}
System.out.println("Result: " + r);
return r;
}
}
现在我们想要使用 Thread
的方式开启一个线程来做这个事情:
Callable<Long> callable = new Task(123450000L);
Thread thread = new Thread(callable); // compile error!
thread.start();
可以看到第二行是编译不通过的。因为 Thread
的方式只接受实现了 Runnable
接口的类。
这时候我们就可以整一个 RunnableAdapter
, 这个 Adapter
就负接受一个 callable
,输出一个 runnable
。
这里使用
Adapter
而不是直接改写原来的Task
类,因为Task
类可能在别的地方使用
这个 RunnableAdapter
接受一个 callable , 返回一个 runnable。
public class RunnableAdapter implements Runnable{
// 引用待转换接口
private Callable<?> callable;
public RunnableAdpater(Callable<> callable){
this.callable = callable;
}
// 实现指定接口
public void run(){
try{
callable.call();
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
可以看到,这里的适配器其实做了一层封装,适配器接收了一个实现
Callable
的callable
对象,然后自己实现了Runnable
接口,重写了run()
方法,在该方法里实现了callable
对象的业务逻辑。
下面就可以用之前的方式来做这个事情了。
Callable<Long> callable = new Task(123450000L);
Thread thread = new Thread(new RunnableAdapter(callable));
thread.start();
5. 总结
-
Adapter
用于将一类对象转换成为符合某个标准的另一类对象 - 实现分为3步:
(1)接受 A 类对象
(2)实现A类对象的业务逻辑
(3)输出符合某个标准的B类对象