轻松搞定适配器设计模式,你来试试这么学~

适配器模式

概述

  • 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以共同工作。
  • 适配器模式主要分为两种:类适配器和对象适配器

适配器模式的基本构成

  • 01)目标角色( Target): 定义Client 使用的接口,可以是具体或抽 象的类、或是接口。
  • 02)被适配角色( Adaptee): 这个角色有一个已存在并使用了的接口,而这个接口是需要适配的
  • 03)适配器角色( Adapter) :这个适配器模式的核心。它将被适配角色已有的接口转换为目标 角色希望的接口。

适配器模式特性

  • 实现对象外部接口的转换
  • 复用现有的某些类
  • 软件设计阶段应优先考虑接口统一,避免适配器模式的滥用.

适配器的利:

  • 能提高类的透明性和复用,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,现有的类复用但不需要改变,而且提高了适配者的复用性,同一适配者类可以在多个不 同的系统中复用。
  • 目标类和适配器类解耦,通过引入一个适配器类来重用现有的适配者类,无需修改原有结构,提高程序扩展性。
  • 灵活性和扩展性都非常好,通过使用配置文件,可以很方便的更换适配器,也可以在不修改原有代码的基础上,增加新的适配器,符合开闭原则。

适配器的弊:

  • 增加系统代码可读的难度。
  • 只能一对一,不能一对多(一次最多只能适配一个适配者类,不能同时适配多个适配者。)
  • 适配器编写过程需要全面考虑,可能会增加系统的复杂性。

类适配器原理:

  1. 创建一个目标(Target)接口或者目标(Target)抽象类,也可以是一个具体类
  2. 创建一个适配器类(Adapter),同时继承被适配类(Adaptee)并实现目标接口
  3. 在适配器类中重写目标接口或者目标抽象类的方法
  4. 在重写后的方法中通过调用被适配类访问所需要的方法

相关代码:

/**
 * 目标接口
 * @author Savior.D
 */
interface Target {
	public abstract void request();
}

/**
 * 需要被适配的类
 */
class Adaptee {
	public void adpateeRequest() {
		System.out.println("我是被适配者的请求方法");
	}
}

/**
 * 适配器
 */
class Adapter extends Adaptee implements Target {
    //重写目标接口中的方法
	@Override
	public void request() {
     //通过适配器类调用访问所需要被适配类中的方法
     super.adpateeRequest();
	}

}

对象适配器原理:

  1. 创建一个目标(Target)接口
  2. 创建一个适配器类(Adapter)实现目标接口
  3. 在适配器类中重写目标接口中的方法
  4. 在类中创建私有的被适配类的对象
  5. 在重写后的方法中通过调用被适配类的对象访问所需要的方法

相关代码:

/**
 * 目标接口
 * 
 * @author Savior.D
 */
interface Target {
	public abstract void request();
}

/**
 * 需要被适配的类
 */
class Adaptee {
	public void adpateeRequest() {
		System.out.println("我是被适配者的请求方法");
	}
}

/**
 * 适配器
 */
class Adapter implements Target {
	//创建私有的被适配类的对象
	private static Adaptee adaptee;

	@Override
	public void request() {
    //通过被适配器类的对象调用其中所需要的方法
      adaptee.adpateeRequest();
	}

接下来让我们看一个具体的场景设计样例子:

利用适配器模式实现外籍球员通过翻译者(相当于实现语言转换的适配器) ,在接受不同训练指令(即接口调用)时,与其他球员以一致的训练指令进行训练的过程。在.上述设计的场景中将球员分为三类,即前锋、中锋、后卫,同时每类球员的训练指令简化为:进攻和防守两种。此外,设定有一位外籍中锋球员,该球员通过翻译接受命令进行训练。

具体类图:
具体的类图构建

球员类的代码:

**
 *球员类,所有非外籍球员的父类
 */
class BasketballPlayer{
	private String name;
	
	
	public BasketballPlayer(String name) {
		super();
		this.setName(name);
	}


	public BasketballPlayer() {
		super();
	}


	public void attack() {
		System.out.println("进攻");
	}
	public void defense() {
		System.out.println("防守");
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}
}


/**
 * 非外籍前锋类
 */
class Forward extends BasketballPlayer{

	public Forward() {
		super();
	}
	
	public Forward(String name) {
		super(name);
	}

	@Override
	public void attack() {
		System.out.println("前锋"+super.getName()+"进攻");
	}

	@Override
	public void defense() {
		System.out.println("前锋"+super.getName()+"防守");
	}
	
}


/**
 *非外籍控球后卫
 */
class PointGuard extends BasketballPlayer{

	public PointGuard() {
		super();
	}

	public PointGuard(String name) {
		super(name);
	}

	@Override
	public void attack() {
		System.out.println("控球后卫"+super.getName()+"进攻");
	}

	@Override
	public void defense() {
		System.out.println("控球后卫"+super.getName()+"防守");
	}
	
	
}


/**
 * 非外籍中锋
 */
class CentreForward extends BasketballPlayer{

	public CentreForward() {
		super();
	}

	public CentreForward(String name) {
		super(name);
	}

	@Override
	public void attack() {
		System.out.println("中锋"+super.getName()+"进攻");
	}

	@Override
	public void defense() {
		System.out.println("中锋"+super.getName()+"防守");
	}

}

运用适配器模式的翻译者代码:

/**
 * 此处运用类适配器的设计模式
 * 这里的翻译者就相当于一个适配器
 * 通过他 转换外籍球员将可以正常的进攻和防守
 */
class Translator extends BasketballPlayer{
	//创建外籍球员的实例
	private ForeignCentreForward fcf=new ForeignCentreForward();
	public Translator() {
		super();
	}

	public Translator(String name) {
		fcf.setName(name);
	}

	/* 重写球员类的进攻方法
	 * 在里面通过外籍球员实例的调用实现外籍球员的进攻
	 * @see com.duanping.demos.BasketballPlayer#attack()
	 */
	@Override
	public void attack() {
		fcf.gongji();
	}

	/* 重写球员类的防守方法
	 * 在里面通过外籍球员实例的调用实现外籍球员的防守
	 * @see com.duanping.demos.BasketballPlayer#defense()
	 */
	@Override
	public void defense() {
		fcf.fanshou();
	}
	
}

等待被匹配的外籍球员的相关代码:

/**
 * 外籍中锋,有自己的进攻方式和防守方式,但是因为是外籍球员,
 * 沟通不便,进攻防守方面会受到影响
 */
class ForeignCentreForward{
	private String name;

	public ForeignCentreForward() {
		super();
	}

	public ForeignCentreForward(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	//外籍球员的进攻,等待被匹配
	public void gongji() {
		System.out.println("外籍中锋"+name+"进攻");
	}
	
	//外籍球员的防守,等待被匹配
	public void fanshou() {
		System.out.println("外籍中锋"+name+"防守");
	}
	
}

如果觉得本篇文章对你有所帮助,可以点个赞~,谢谢支持

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值