【正文】
我们知道,Android中最重要也是最难用的UI控件就是ListView列表控件,而要想灵活运用它,则必须要用到适配器adapter,所以,我觉得还是很有必要来学习一下Java当中的适配器模式(不管以后能不能用到),毕竟Java语言是Android开发很重要的一个基础。
完全了解适配器模式,有很多知识要学习,例如:适配器模式有类的适配器模式和对象的适配器模式两种不同的形式。但作为初学者,我就简单学习一下配器模式入门知识吧,以后会不断完善。希望奋斗在码农路上的童鞋们莫吐槽→_→
一、适配器介绍:
- 将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- 适配器模式在现代的Java框架中十分常用。这种模式适用于以下场景:想使用一个已存在的类,但是该类不符合接口需求;或者需要创建一个可重用的类,适配没有提供合适接口的其它类。
二、苹果和桔子的例子:
适配器的思想可以通过下面这个简单的例子说明。这个示例要让一个桔子被“适配”成一个苹果。如下图所示:
上图中的下半部分可以看到,适配器包含了一个桔子实例并且继承了苹果类。桔子对象放在了适配器中,于是桔子表现得就像苹果一样了。对应的逻辑图如下:
三、插座盒插头的例子:
上图中,我们可以通过中间的适配器让右边的插头成功连接上左边的插座。
四、插头适配器的代码实现:
1 /** 2 适配器模式( Adapter ):将一个类的接口转换成客户希望的另外一个接口。 3 适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 4 */ 5 class AdapterDemo{ 6 public static void main(String[] args){ 7 //电源A开始工作 8 PowerA powerA = new PowerAImpl(); 9 start(powerA); 10 PowerB powerB = new PowerBImpl(); 11 PowerAAdapter pa = new PowerAAdapter(powerB); 12 start(pa); 13 } 14 //定义方法:电源A工作 15 public static void start(PowerA powerA){ 16 System.out.println("....一些重复的代码....."); 17 powerA.insert(); 18 System.out.println("....一些重复的代码.....\n"); 19 } 20 21 /** 22 public static void start(PowerB powerB){ 23 System.out.println("....一些重复的代码....."); 24 powerB.connect(); 25 System.out.println("....一些重复的代码....."); 26 } 27 */ 28 } 29 //定义适配器类 30 class PowerAAdapter implements PowerA{ 31 private PowerB powerB;//要进行适配的接口 32 33 public PowerAAdapter(PowerB powerB){ 34 this.powerB = powerB; 35 } 36 //实现接口PowerA,则必然要实现PowerA里面的方法 37 public void insert(){ 38 powerB.connect(); 39 } 40 } 41 /** 42 电源A接口 43 */ 44 interface PowerA{ 45 public void insert(); 46 } 47 class PowerAImpl implements PowerA{ 48 public void insert(){ 49 System.out.println("电源A接口插入,开始工作"); 50 } 51 } 52 /** 53 电源B接口 54 */ 55 interface PowerB{ 56 public void connect(); 57 } 58 class PowerBImpl implements PowerB{ 59 public void connect(){ 60 System.out.println("电源B接口已连接,开始工作"); 61 } 62 }
在这个例子当中,我们想让PowerB调用PowerA中Start()方法里的代码;当然,我们也不想重复写被注释掉的23、25行代码。这个时候就可以用适配器模式。
上述代码解释:
第30行:开始定义适配器,也是核心代码的开始;
第33、34行:通过构造方法将PowerB传进来;
第37行代码:既然是实现接口PowerA,则必然要实现PowerA里面的方法insert();
第38行代码:我们在PowerA的insert()方法中,去调用PowerB的connect()方法;
紧接着,第10、11、12行代码的意思是:在new一个PowerB的时候,我们把它传到适配器PowerAAdapter里面去,启动适配器,然后PowerB就会去执行第16、24、18行的代码。
注:16、24、18这个顺序没有错,因为我们在适配器中相当于是已经将24行代码替换为了第17行代码。
运行效果如下:
同理,如果我也想把PowerA作为PowerB去使用,可以再定义一个适配器PowerBAdapter,实现双向适配器。
五、小总结:
上方第23、25行被注释掉的代码,表示是很多重复的代码,不符合面向对象的思维方式。我们现在设想这样一个例子:我们的项目已经上线并且客户正在使用,但是后来增加了一些新的需求。而面向对象有一条OO原则就是:对修改关闭(上线后,代码尽量不要修改,不然可能会发生连锁反应,导致其他调用此处方法的代码都可能出问题),对扩展开放(自己定义的新的方法,别人还没有调用,我们当然可以修改)。此时,我们可以通过适配器来减少这些重复的代码。
六:OO设计原则:
- 面向接口编程(面向抽象编程)
- 封装变化
- 多用组合,少用继承
- 对修改关闭 对扩展开放
个人感觉,这些设计原则,需要在实践中不断加深理解,在这里就不过多描述了哦~