如何在不修改物件的情况上,使用中间层(Adapter)後,能转换跟其他物件联系,同时原有功能不受影响。
这模式在现实最典型的应用是充电器:使用 110v 的电子设备,在国外 220v 的环境下,需要使用「变压器」让「充电」这个目的,仍能实践。
应用在软件开发上,可能有这些应用:
XML
,新系统只提供 JSON
,需要中间层负责转换。简而言之,就是建立一个「转换器」,让系统维持运作。
在实作前,要注意的是判断环境中,目标物件本身是单一物件还是继承虚拟层的物件?而作法则是:
以下 UML 图与范例程序码,采用「目标物件本身继承虚拟层」。
亲代、虚拟层:Car
public abstract class Car {
protected String name;
protected Car(String name) {
this.name = name;
}
public void turnOn() {
System.out.println("发动车子,名称是:" + name);
}
public void turnOff() {
System.out.println("车子熄火");
}
public abstract void turnRight();
public abstract void turnLeft();
public void speedUp() {
System.out.println("脚踩油门");
}
public void brake() {
System.out.println("脚踩煞车");
}
}
子代:LeftHandCar
、RightHandCar
(Adaptee)
public class LeftHandCar extends Car {
public LeftHandCar(String name) {
super(name);
}
@Override
public void turnRight() {
System.out.println("打右转灯");
System.out.println("车辆靠右");
System.out.println("确认没有行人");
System.out.println("确认没有机车");
System.out.println("车辆右转");
}
@Override
public void turnLeft() {
System.out.println("打左转灯");
System.out.println("车辆向左靠近分隔岛");
System.out.println("车辆向前靠近左转区块");
System.out.println("等待左转灯亮起");
System.out.println("左转灯亮起");
System.out.println("车辆左转");
}
}
public class RightHandCar extends Car {
public RightHandCar(String name) {
super(name);
}
@Override
public void turnRight() {
System.out.println("打右转灯");
System.out.println("车辆向右靠近分隔岛");
System.out.println("车辆向前靠近右转区块");
System.out.println("等待右转灯亮起");
System.out.println("右转灯亮起");
System.out.println("车辆右转");
}
@Override
public void turnLeft() {
System.out.println("打左转灯");
System.out.println("车辆靠左");
System.out.println("确认没有行人");
System.out.println("确认没有机车");
System.out.println("车辆左转");
}
}
右驾车适应在左驾环境:RightHandInLeftHandTraffic
(Adapter)
public class RightHandInLeftHandTraffic extends RightHandCar {
public RightHandInLeftHandTraffic(String name) {
super(name);
}
@Override
public void turnRight() {
System.out.println("打右转灯");
System.out.println("车辆靠右");
System.out.println("确认没有行人");
System.out.println("确认没有机车");
System.out.println("车辆右转");
}
@Override
public void turnLeft() {
System.out.println("打左转灯");
System.out.println("车辆向左靠近分隔岛");
System.out.println("车辆向前靠近左转区块");
System.out.println("等待左转灯亮起");
System.out.println("左转灯亮起");
System.out.println("车辆左转");
}
}
在左驾的环境上路:LeftHandTraffic
public class LeftHandTraffic {
public static void main(String[] args) {
System.out.println("---国产车上路罗---");
Car domesticCar = new LeftHandCar("Altis");
domesticCar.turnOn();
domesticCar.speedUp();
domesticCar.brake();
domesticCar.turnRight();
domesticCar.speedUp();
domesticCar.brake();
domesticCar.turnLeft();
domesticCar.turnOff();
System.out.println("\n---完美,下车换日本进口车---");
Car madeInJapanCar = new RightHandInLeftHandTraffic("CT 200h");
madeInJapanCar.turnOn();
madeInJapanCar.speedUp();
madeInJapanCar.brake();
madeInJapanCar.turnRight();
madeInJapanCar.speedUp();
madeInJapanCar.brake();
madeInJapanCar.turnLeft();
madeInJapanCar.turnOff();
System.out.println("\n---测试完成,左驾右驾都很棒---");
}
}
亲代、虚拟层:Car
/** @abstract */
class Car {
constructor(name) {
this.name = name;
}
turnOn() {
console.log("发动车子,名称是:" + this.name);
}
turnOff() {
console.log("车子熄火");
}
/** @abstract */
turnRight() { return; }
/** @abstract */
turnLeft() { return; }
speedUp() {
console.log("脚踩油门");
}
brake() {
console.log("脚踩煞车");
}
}
子代:LeftHandCar
、RightHandCar
(Adaptee)
class LeftHandCar extends Car {
constructor(name) {
super(name);
}
/** @override */
turnRight() {
console.log("打右转灯");
console.log("车辆靠右");
console.log("确认没有行人");
console.log("确认没有机车");
console.log("车辆右转");
}
/** @override */
turnLeft() {
console.log("打左转灯");
console.log("车辆向左靠近分隔岛");
console.log("车辆向前靠近左转区块");
console.log("等待左转灯亮起");
console.log("左转灯亮起");
console.log("车辆左转");
}
}
class RightHandCar extends Car {
constructor(name) {
super(name);
}
/** @override */
turnRight() {
console.log("打右转灯");
console.log("车辆向右靠近分隔岛");
console.log("车辆向前靠近右转区块");
console.log("等待右转灯亮起");
console.log("右转灯亮起");
console.log("车辆右转");
}
/** @override */
turnLeft() {
console.log("打左转灯");
console.log("车辆靠左");
console.log("确认没有行人");
console.log("确认没有机车");
console.log("车辆左转");
}
}
右驾车适应在左驾环境:RightHandInLeftHandTraffic
(Adapter)
class RightHandInLeftHandTraffic extends RightHandCar {
constructor(name) {
super(name);
}
/** @override */
turnRight() {
console.log("打右转灯");
console.log("车辆靠右");
console.log("确认没有行人");
console.log("确认没有机车");
console.log("车辆右转");
}
/** @override */
turnLeft() {
console.log("打左转灯");
console.log("车辆向左靠近分隔岛");
console.log("车辆向前靠近左转区块");
console.log("等待左转灯亮起");
console.log("左转灯亮起");
console.log("车辆左转");
}
}
在左驾的环境上路:LeftHandTraffic
const leftHandTraffic = () => {
console.log("---国产车上路罗---");
const domesticCar = new LeftHandCar("Altis");
domesticCar.turnOn();
domesticCar.speedUp();
domesticCar.brake();
domesticCar.turnRight();
domesticCar.speedUp();
domesticCar.brake();
domesticCar.turnLeft();
domesticCar.turnOff();
console.log("\n---完美,下车换日本进口车---");
const madeInJapanCar = new RightHandInLeftHandTraffic("CT 200h");
madeInJapanCar.turnOn();
madeInJapanCar.speedUp();
madeInJapanCar.brake();
madeInJapanCar.turnRight();
madeInJapanCar.speedUp();
madeInJapanCar.brake();
madeInJapanCar.turnLeft();
madeInJapanCar.turnOff();
console.log("\n---测试完成,左驾右驾都很棒---");
}
leftHandTraffic();
Adapter 是非常容易理解的模式,理解是「专接器」後几乎懂含义。
倒是有几点要思考:
除了今天介绍的应用,C++
允许多重继承,所以 Adapter 有另一种写法,但想想这不是 Java
与 JavaScript
能实作的,便不深究了。
明天将介绍 Structural patterns 的第二个模式:Bridge 模式。
>>: 学习Python纪录Day11 - 开启文字档案与写入资料
今日练习档 ԅ( ¯་། ¯ԅ) 大家好呀 ٩(ˊ〇ˋ*)و 列印我相信也是很多人会使用的一个功能,...
MSW实战 今天我们来实战一个msw的使用,首先我们先随意建立一个component,我是建立一个U...
K8s除了自带的Ingress Gateway外,还可以透过Istio Ingress Gatewa...
我想大部分的人学测试不是想用在写 leetcode 吧,因此我们来模拟一下购物车。 我们来写一个有点...
Blue Prism拯救贫穷大作战第一弹-汇入MS Excel VBO 近期与之前工作的同事於lin...