设计模式四之适配器模式和外观模式
1. 适配器模式:将一个对象包装起来以改变其接口
装饰者模式:将一个对象包装起来以增加新的行为和责任
外观模式:将一群对象包装起来以简化其接口
以上,是3种模式的区别,接下来,我们详细介绍适配器模式和外观模式。
2. 适配器模式:
eg:有一个鸭子接口,火鸡接口和火鸡实例,但是没有鸭子实例。
客户需要一个鸭子实例,具体实现思路是将火鸡包装成一个鸭子的实例,供客户使用。
(1) 鸭子接口
public interface Duck { //鸭子叫 public void quack(); //鸭子飞 public void fly(); }
(2) 火鸡接口
public interface Turkey { //火鸡叫 public void gobble(); //火鸡飞 public void fly(); }
(3)火鸡实例
public class WildTurkey implements Turkey { @Override public void gobble() { // TODO Auto-generated method stub System.out.println("Gobble gobble"); } @Override public void fly() { // TODO Auto-generated method stub System.out.println("I am flying a short distance"); } }
(4)现在我们需要一个火鸡适配器,将火鸡封装成鸭子对象。供客户使用
//要提供给外界一个Duck的接口,所以要继承Duck接口,但是所有的实例行为全部都是火鸡的行为 public class TurkeyAdaptor implements Duck { Turkey turkey; public TurkeyAdaptor(Turkey turkey) { this.turkey = turkey; } @Override public void quack() { // TODO Auto-generated method stub //但是真正的对象是一个火鸡对象,所以拥有的行为仍然是火鸡的行为 turkey.gobble(); } @Override public void fly() { // TODO Auto-generated method stub
//火鸡飞行时间较短,所以循环5次,模拟成为鸭子的飞行状态 for(int i=0; i<5; i++) { turkey.fly(); } } }
(5)做测试
public static void main(String[] args) { //测试简单的duck对象 Duck duck = new MallardDuck(); duck.quack(); duck.fly(); System.out.println('\n'); //测试简单的火鸡对象 Turkey turkey = new WildTurkey(); turkey.gobble(); turkey.fly(); System.out.println('\n'); //测试包装成duck的火鸡对象 Duck duck2 = new TurkeyAdaptor(turkey); duck2.fly(); duck2.quack(); System.out.println('\n'); }
以上,我们完成了将火鸡,包装成鸭子,将鸭子提供给客户使用的过程,这就是我们常说的适配器模式,将接口封装成客户需要的另一个接口。
适配器模式分为类的适配器模式和对象的适配器模式,以上讲的是对象的适配器模式,采用的是组合的方式,将鸭子和火鸡的行为组合在一起。
类的适配器模式利用了多继承,由于java中没有多继承这一说,所以我们不详细讲解,只需要知道类的适配器模式采用的是继承的方式而非组合。
3. 外观模式:
提供了一个统一的接口,用来访问子系统中的一群接口,让子系统更容易使用,让用户使用起来只看得到简化之后的接口,方便用户的体验。
4. 当需要使用一个现有的类,但是此类的接口不符合用户的需求的时候,就要用到适配器。
当需要简化一个很大的接口或者一群复杂的接口时,需要用到外观模式,但是具体的行为实现都是在子系统中实现的,简化之后的接口只负责调用以及和用户交互。
装饰者是为了给系统加入新的行为或者功能,所以大部分使用装饰者模式的系统都是需要扩展的系统。