适配器模式

先看一个案例:

1.1 厨师主业务接口

1 package com.monkey1024.worker;
2 
3 // 厨师主业务接口
4 public interface ICooker {
5     
6     // 烹饪
7      String cookeing();
8 
9 }

   

1.2.程序员主业务接口

1 package com.monkey1024.worker;
2 
3 // 程序员主业务接口
4 public interface IProgrammer {
5 
6     // 编程
7     String programming();
8 
9 }

2.1 京东程序员

 1 package com.monkey1024.worker.imp;
 2 
 3 import com.monkey1024.worker.IProgrammer;
 4 
 5 
 6 // 京东程序员 (实现类)
 7 public class JdProgrammer implements IProgrammer {
 8 
 9     @Override
10     public String programming() {
11         return "码农:我能骚出一手好代码";
12     }
13 
14 }

2.2 全聚德厨师

 1 package com.monkey1024.worker.imp;
 2 
 3 import com.monkey1024.worker.ICooker;
 4 
 5 // 全聚德厨师 (实现类)
 6 public class QjdCooker implements ICooker {
 7 
 8     @Override
 9     public String cookeing() {
10         return "厨师:我能烧出一只好鸭子";
11     }
12 
13 }

3 测试类

 1 package com.monkey1024.test;
 2 
 3 import com.monkey1024.worker.ICooker;
 4 import com.monkey1024.worker.imp.JdProgrammer;
 5 import com.monkey1024.worker.imp.QjdCooker;
 6 
 7 public class MyTest {
 8 
 9     public static void main(String[] args) {
10         
11         // 雇一个全聚德的厨师
12         ICooker c = new QjdCooker();
13         
14         // 抓一个京东的程序员
15         JdProgrammer p = new JdProgrammer();
16         
17         // 分别做自我技艺介绍
18         
19         System.out.println(c.cookeing());
20         
21         System.out.println(p.programming());
22         
23 
24     }
25 
26 }

运行结果:

厨师:我能烧出一只好鸭子
码农,我能骚出一手好代码

使用一个适配器编程

1.1 厨师主业务接口

1 package com.monkey1024.worker;
2 
3 // 厨师主业务接口
4 public interface ICooker {
5     
6     // 烹饪
7      String cookeing();
8 
9 }

   

1.2.程序员主业务接口

1 package com.monkey1024.worker;
2 
3 // 程序员主业务接口
4 public interface IProgrammer {
5 
6     // 编程
7     String programming();
8 
9 }

2.1 京东程序员

 1 package com.monkey1024.worker.imp;
 2 
 3 import com.monkey1024.worker.IProgrammer;
 4 
 5 
 6 // 京东程序员 (实现类)
 7 public class JdProgrammer implements IProgrammer {
 8 
 9     @Override
10     public String programming() {
11         return "码农:我能骚出一手好代码";
12     }
13 
14 }

2.2 全聚德厨师

 1 package com.monkey1024.worker.imp;
 2 
 3 import com.monkey1024.worker.ICooker;
 4 
 5 // 全聚德厨师 (实现类)
 6 public class QjdCooker implements ICooker {
 7 
 8     @Override
 9     public String cookeing() {
10         return "厨师:我能烧出一只好鸭子";
11     }
12 
13 }

3.1 适配器接口

 1 package com.monkey1024.adapters;
 2 
 3 // 适配器接口
 4 public interface IWorkerAdapter {
 5     
 6     // 形参是Object类型的工作岗位
 7     // 你给我传一个什么岗位,我就给你相应的String类型的工作
 8     String work(Object worker);
 9     
10 }

3.2 适配器类

 1 package com.monkey1024.adapters.impl;
 2 
 3 import com.monkey1024.adapters.IWorkerAdapter;
 4 import com.monkey1024.worker.ICooker;
 5 import com.monkey1024.worker.IProgrammer;
 6 
 7 
 8 // 适配器类!!!
 9 public class WorkerAdapter implements IWorkerAdapter {
10 
11     @Override
12     public String work(Object worker) {
13         
14         // 给工作内容赋值一个 空字符串 。 
15         String workContent ="";
16         
17         //做判断
18         
19         // 判断传过来的对象是不是 一个 厨师类型,是则调用其cookeing()
20         if(worker instanceof ICooker) {
21             
22             // 厨师向经理介绍自己的技能
23             workContent =((ICooker) worker).cookeing();  
24             
25             
26             // 判断传递过来的是不是 一个 程序员类型,是则调用其programming()
27         }else if(worker instanceof IProgrammer){
28             
29             // 程序员向经理介绍自己的技能
30             workContent =((IProgrammer) worker).programming();
31             
32         }else {
33             System.out.println("抱歉,你不是我们要招聘的人才类型");
34             
35         }
36         
37         return workContent;
38     }
39 
40 }

4. 测试类

 1 package com.monkey1024.test;
 2 
 3 import com.monkey1024.adapters.IWorkerAdapter;
 4 import com.monkey1024.adapters.impl.WorkerAdapter;
 5 import com.monkey1024.worker.ICooker;
 6 import com.monkey1024.worker.imp.JdProgrammer;
 7 import com.monkey1024.worker.imp.QjdCooker;
 8 
 9 public class MyTest {
10 
11     public static void main(String[] args) {
12         
13         // 雇一个全聚德的厨师
14         ICooker c = new QjdCooker();
15         
16         // 抓一个京东的程序员
17         JdProgrammer p = new JdProgrammer();
18         
19          
20         // 建一个Object数组,用于存放 这些 员工们
21         Object[] workers = {c , p};
22         
23         
24         // 创建适配器对象
25         IWorkerAdapter adapter = new WorkerAdapter();
26         
27         
28         // 循环遍历每个工种对象,让每个工种对象在适配器中逐个进行匹配
29         for (Object worker  : workers) {
30             
31             
32             String workContent = adapter.work(worker);
33             
34             // 输出 员工工种 的相应工作内容
35             System.out.println(workContent);
36             
37         }
38 
39     }
40 
41 }

运行结果:

厨师:我能烧出一只好鸭子
码农:我能骚出一手好代码

使用多个适配器编程:(推荐使用这种,因为在后期的框架源码中 使用的就是这种)

1 -2 步骤代码与上个案例的一样.

3.1 总适配器接口

 1 package com.monkey1024.adapters;
 2 
 3 // 总适配器接口
 4 public interface IWorkerAdapter {
 5     
 6     // 形参是Object类型的工作岗位
 7     // 你给我传一个什么工种,我就给你相应的String类型的工作
 8     String work(Object worker);
 9     
10     
11     // 判断 工种与适配器是否 对应
12     boolean supports(Object worker);
13     
14 }

3.2 厨师适配器类

 1 package com.monkey1024.adapters.impl;
 2 
 3 import com.monkey1024.adapters.IWorkerAdapter;
 4 import com.monkey1024.worker.ICooker;
 5 
 6 // 厨师适配器类
 7 public class CookerAdapter implements IWorkerAdapter {
 8 
 9     @Override
10     public String work(Object worker) {
11         
12         // 返回 厨师 对应的工作内容
13         return ((ICooker)worker).cookeing();
14         
15     }
16 
17     @Override
18     public boolean supports(Object worker) {
19         
20         // 判断 worker是不是 厨师
21         return (worker instanceof ICooker); 
22     }
23 
24 }

3.3 程序员适配器类

 1 package com.monkey1024.adapters.impl;
 2 
 3 import com.monkey1024.adapters.IWorkerAdapter;
 4 import com.monkey1024.worker.IProgrammer;
 5 
 6 // 程序员接口
 7 public class ProgrammerAdapter implements IWorkerAdapter {
 8 
 9     @Override
10     public String work(Object worker) {
11         //// 返回 程序员 对应的工作内容
12         return ((IProgrammer)worker).programming();
13     }
14 
15     @Override
16     public boolean supports(Object worker) {
17         // 判断工种是不是 程序员
18         return (worker instanceof IProgrammer);
19     }
20 
21 }

4. 测试类

 1 package com.monkey1024.test;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import com.monkey1024.adapters.IWorkerAdapter;
 7 import com.monkey1024.adapters.impl.CookerAdapter;
 8 import com.monkey1024.adapters.impl.ProgrammerAdapter;
 9 import com.monkey1024.worker.ICooker;
10 import com.monkey1024.worker.imp.JdProgrammer;
11 import com.monkey1024.worker.imp.QjdCooker;
12 
13 public class MyTest {
14 
15     public static void main(String[] args) {
16         
17         // 雇一个全聚德的厨师
18         ICooker c = new QjdCooker();
19         // 抓一个京东的程序员
20         JdProgrammer p = new JdProgrammer();
21          
22         // 建一个Object数组,用于存放 这些 员工们
23         Object[] workers = {c , p};
24         
25          
26         // 循环遍历每个工种对象,让每个工种对象在适配器中逐个进行匹配
27         for (Object worker  : workers) {
28             
29             // 拿到该 工种对应的适配器
30             // 怎么拿?先拿到所有的适配器,再在其中寻找自己要的
31                   IWorkerAdapter adapter= getAdapter(worker);
32                   System.out.println(adapter.work(worker));
33         }
34 
35     }
36 
37     
38     // 根据worker获取相应的适配器对象
39     private static IWorkerAdapter getAdapter(Object worker) {
40         
41         // 先拿到所有的适配器
42         List<IWorkerAdapter> adapters = getAllAdapters();
43         
44         // 遍历所有的适配器
45         for (IWorkerAdapter adapter : adapters) {
46             
47             // 如果 传递进来的工种 能够 匹配上 对应的 适配器
48             if(adapter.supports(worker)) {
49                 
50                 return adapter;
51                 
52             }
53         }
54         return null;
55         
56     }
57 
58     // 获取所有的适配器
59     private static List<IWorkerAdapter> getAllAdapters() {
60         
61         // 创建一个list集合 ,用于存放 所有的适配器
62         List<IWorkerAdapter> adapters = new ArrayList<>();    
63         
64         // 存放 厨师适配器
65         adapters.add(new CookerAdapter());
66         
67         // 存放 程序员适配器
68         adapters.add(new ProgrammerAdapter());
69         
70         
71         // 返回这个List集合
72         return adapters;
73     }
74     
75      
76 
77 }

缺省适配器模式   (是适配器模式的简易版)

  缺省适配器模式是由适配器模式简化而来,省略了适配器模式中目标接口,也就是源接口和目标接口相同,源接口为接口,目标接口为类。


  典型的缺省适配器模式是 JavaEE 规范中的 Servlet 接口与 GenericServlet 抽象类。

  Servlet 接口中包含五个抽象方法,而其中的 service()方法才是用于实现业务逻辑的、必须要实现的方法,另外四个方法一般都是空实现,或简单实现。

  GenericServlet 抽象类实现了 Servlet 接口的 service()方法以外的另外四个方法,所以自定义的 Servlet 只需要继承 GenericServlet 抽象类,实现 service()方法即可。无需再实现Servlet 接口了。



原文地址:https://www.cnblogs.com/penguin1024/p/11809642.html