设计模式之适配器模式

1.定义

适配器模式将一个类的接口,转换成客户期望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

2.适配器分类

(1)组合
采用组合方式的适配器称为对象适配器。
特点:把“被适配者”作为一个对象组合到适配器类中,以修改目标接口包装被适配者。

(2)继承(Java是单继承)
采用继承方式的适配器称为类适配器。
特点:通过多重继承不兼容接口,实现对目标接口的匹配,单一的为某个类而实现适配

区别:
组合的方式可以适配被适配者的任何子类。由于Java是单继承的,继承的方式继承了被适配者,是为这个类单一服务的,不能再继承被适配者的任何子类。

3.组合实现

/*
 * 三相插座接口
 */
public interface ThreePlugIf {
	// 使用三相插座供电
	public void powerWithThreePlug();
}
/*
 * 二相插座接口
 */
public interface TwoPlugIf {
	//使用二相插座供电
	public void powerWithTwoPlug();
}
/*
 * 二相插座类
 */
public class TwoPlug implements TwoPlugIf {
	// 使用二相插座供电
	public void powerWithTwoPlug() {
		System.out.println("使用二相插座供电");
	}
}
/*
 * 二相转三相插座适配器
 */
public class Two2ThreeAdapter implements ThreePlugIf {
	private TwoPlug plug;

	public Two2ThreeAdapter(TwoPlug plug) {
		this.plug = plug;
	}

	@Override
	public void powerWithThreePlug() {
		System.out.print("组合方式:");
		plug.powerWithTwoPlug();
	}
}
/*
 * 笔记本类
 */
public class NoteBook {
	private ThreePlugIf plug;

	public NoteBook(ThreePlugIf plug) {
		this.plug = plug;
	}

	// 使用插座充电
	public void powerWithPlug() {
		plug.powerWithThreePlug();
	}

	public static void main(String[] args) {
		TwoPlug two = new TwoPlug();
		ThreePlugIf three = new Two2ThreeAdapter(two);
		NoteBook nb = new NoteBook(three);
		nb.powerWithPlug();
	}

}

运行结果:

组合方式:使用二相插座供电

4.继承实现

/*
 * 三相插座接口
 */
public interface ThreePlugIf {
	//使用三相插座供电
	public void powerWithThreePlug();
}
/*
 * 二相插座接口
 */
public interface TwoPlugIf {
	//使用二相插座供电
	public void powerWithTwoPlug();
}
/*
 * 二相插座类
 */
public class TwoPlug implements TwoPlugIf {
	// 使用二相插座供电
	public void powerWithTwoPlug() {
		System.out.println("使用二相插座供电");
	}
}
/*
 * 二相转三相插座适配器
 */
public class Two2ThreeAdapter extends TwoPlug implements ThreePlugIf {
	@Override
	public void powerWithThreePlug() {
		System.out.print("继承方式:");
		this.powerWithTwoPlug();
	}
}
/*
 * 笔记本类
 */
public class NoteBook {
	private ThreePlugIf plug;

	public NoteBook(ThreePlugIf plug) {
		this.plug = plug;
	}

	// 使用插座充电
	public void powerWithPlug() {
		plug.powerWithThreePlug();
	}

	public static void main(String[] args) {
		ThreePlugIf three = new Two2ThreeAdapter();
		NoteBook nb = new NoteBook(three);
		nb.powerWithPlug();
	}

}

运行结果:

继承方式:使用二相插座供电

5.另一个例子:火鸡to鸭子转换器

/*
 * 鸭子基类
 */
public interface Duck {
	public void quack();

	public void fly();
}
/*
 * 绿头鸭是鸭子的子类,实现了鸭子的呱呱叫和飞行的能力
 */
public class MallardDuck implements Duck {

	@Override
	public void quack() {
		System.out.println("Quack");
	}

	@Override
	public void fly() {
		System.out.println("I'm flying");
	}

}
public interface Turkey {
	// 火鸡不会呱呱叫,只会咯咯叫
	public void gobble();

	// 火鸡会飞,虽然飞不远
	public void fly();
}
/*
 * 野生火鸡
 */
public class WildTurkey implements Turkey {

	@Override
	public void gobble() {
		System.out.println("Gobble gobble");
	}

	@Override
	public void fly() {
		System.out.println("I'm flying a short distance");
	}
}
/*
 * 现在,假设你缺鸭子对象,想用一些火鸡对象来冒充。
 * 显而易见,因为火鸡的接口不同,所以我们不能公然拿来用。
 * 那么,写个适配器吧
 */
public class Turkey2DuckAdapter implements Duck {

	private Turkey turkey;

	public Turkey2DuckAdapter(Turkey turkey) {
		this.turkey = turkey;
	}

	// 现在我们需要实现接口中所有的方法。quack()在类之间的转换很简单,
	// 只要调用gobble()接可以了
	@Override
	public void quack() {
		turkey.gobble();
	}

	// 固然两个接口都具备了fly()方法,火鸡的飞行距离很短,不像鸭子可以长途飞行。
	// 要让鸭子的飞行和火鸡的飞行能够对应,必须连续五次调用火鸡的fly()来完成
	@Override
	public void fly() {
		for (int i = 0; i < 5; i++) {
			turkey.fly();
		}
	}
}
/*
 * 基于火鸡的鸭子
 */
public class DuckBaseTurkey {
	private Duck duck;
	
	public DuckBaseTurkey(Duck duck) {
		this.duck = duck;
	}
	
	public void quack() {
		duck.quack();
	}
	
	public void fly() {
		duck.fly();
	}
	
	public static void main(String[] args) {
		Turkey turkey = new WildTurkey();
		Duck duck = new Turkey2DuckAdapter(turkey);
		DuckBaseTurkey dbt = new DuckBaseTurkey(duck);
		dbt.quack();
		dbt.fly();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值