结构型模式主要讲述如何组合类和对象以获取更大功能的结构,同样,按照模式的主要用途,结构型模式也分为两个层次:
1、结构型类模式,采用继承机制来组合接口,java没有多继承功能,但是可以实现(implements)多个接口,实现了多个父接口的类便拥有了父接口的功能,GOF给出的结构型类模式只有一个,那就是Adapter(适配器)模式,适配器模式的实现还可以用对象模式,一会儿会给出例子。
2、结构型对象模式,该类型的模式不是对接口进行组合,而是描述如何对一些对象进行组合,从而实现一些新功能。因为它可以在运行时刻改变对象的组合关系,所以对象组合方式具有更大的灵活性,这是用静态类组合所不能达到的。现在以适配器为首篇,总结一下结构型模式。
GOF对适配器下的定义为:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。比如说,A要实现一个功能,而类似的功能B已经对其进行了实现,但是A又不能直接调用B的功能,怎么办呢?这时可以新创建一个类,使得该类同时具有A和B的功能属性,这样问题不就解决了,实现方案有两种,分别是类适配器和对象适配器,首先总结类适配器模式,结构图如下:
因为Java不支持多继承机制,所以将要实现的目标功能类设置为Interface类型,代码如下:
1 package adapter; 2 3 public class Test { 4 public static void main(String[] args) { 5 Target target=new Adapter(); 6 target.Request(); 7 } 8 } 9 10 interface Target{ 11 public void Request(); 12 } 13 class Adaptee{ 14 public void SpecificRequest(){ 15 System.out.println("this is specific request"); 16 } 17 } 18 class Adapter extends Adaptee implements Target{ 19 20 @Override 21 public void Request() { 22 // TODO Auto-generated method stub 23 super.SpecificRequest(); 24 } 25 }
使用类适配器模式有很大的限制,Java本身的单继承的语言,如果我们要适配多个功能时该怎么办?若用类适配器模式的话,我们的继承层次会很多,并且根据组合优先于继承的准则,我们也应该尽可能少地使用继承,下面总结对象适配器模式,结构图如下:
对应的代码如下:
1 package adapter; 2 public class Test { 3 public static void main(String[] args) { 4 Target target=new Adapter(new Adaptee()); 5 target.Request(); 6 } 7 } 8 interface Target{ 9 public void Request(); 10 } 11 class Adaptee{ 12 public void SpecificRequest(){ 13 System.out.println("this is specific request"); 14 } 15 } 16 class Adapter implements Target{ 17 private Adaptee adaptee; 18 public Adapter(Adaptee adaptee){ 19 this.adaptee=adaptee; 20 } 21 @Override 22 public void Request() { 23 // TODO Auto-generated method stub 24 adaptee.SpecificRequest(); 25 } 26 }
对象适配器并未继承待适配的类Adaptee,而是利用Adaptee对象直接访问其要适配的方法,好处就是我们多种不同的源(Adaptee)适配到同一个目标中去,但是我们无法对院类的方法进行置换(Override),因为我们并未继承Adaptee类,所以这点是做不到的,因此,要根据实际情况,分析应该采用类适配器还是对象适配器。