实例说明
对于刚从工厂生产出来的商品,有些功能并不能完全满足用户的需要。因此,用户通常会对其进行一定的改装工作。本实例将为普通的汽车增加GPS定位功能,借此演示适配器模式的用法。
实现过程
编写类Car,在该类中,首先定义两个属性,一个是name,表示汽车的名字;另一个是speed,表示汽车的速度。并为其提供getXxx()和setXxx()方法,然后通过重写toString()方法来方便输出Car对象。
Car.java
public class Car { private String name; private double speed; public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSpeed() { return speed; } public void setSpeed(double speed) { this.speed = speed; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("车名:" + name + ","); sb.append("速度:" + speed + "千米/小时"); return sb.toString(); }}
再编写接口GPS,该接口定义了getLocation()方法,用来确定汽车的位置。
GPS.java
import java.awt.Point;public interface GPS { Point getLocation();}
再编写类GPSCar,该类继承Car并实现GPS接口。在该类中首先实现getLocation()方法,用于实现确定汽车位置的功能,然后重写toString()方法方便输出GPSCar对象。
GPSCar.java
import java.awt.Point;public class GPSCar extends Car implements GPS { @Override public Point getLocation() { Point point = new Point(); point.setLocation(super.getSpeed(), super.getSpeed()); return point; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()); sb.append(",坐标:(" + getLocation().x + "," + getLocation().y + ")"); return sb.toString(); } }
可以使用super关键字调用父类中定义的方法。
再编写类Test进行测试。在该类中,分别创建Car和GPSCar对象,并对其初始化,然后输出这两个对象。
Test.java
public class Test { public static void main(String[] args) { System.out.println("自定义普通的汽车:"); Car car = new Car(); car.setName("Adui"); car.setSpeed(60); System.out.println(car); System.out.println("自定义GPS汽车:"); GPSCar gpsCar = new GPSCar(); gpsCar.setName("Audi"); gpsCar.setSpeed(60); System.out.println(gpsCar); }}
编译运行
$javac Car.java GPS.java GPSCar.java Test.java
$java Test
自定义普通的汽车:
车名:Adui,速度:60.0千米/小时
自定义GPS汽车:
车名:Audi,速度:60.0千米/小时,坐标:(60,60)
技术要点
适配器模式可以在符号OCP原则(开闭原则)的基础上,为类增加新的功能。该模式涉及的角色主要有以下3个。
目标角色:就是期待得到的接口,如本实例的GPS接口。
源角色:需要被增加功能的类或接口,如本实例的Car类。
适配器角色:新创建的类,在源角色的基础上实现了目标角色,如本实例的GPSCar类。
适配器模式(Adapter)
意图
将一个类的接口转换成另外一个客户希望的接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适用性
1、你想使用一个已经存在的类,而它的接口不符合你的需求。
2、你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
3、(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
人生没有彩排,每天都是现场直播。