设计模式之结构型模式: 适配器模式
一、简介
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。
实例:美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V
#!/usr/bin/env python # -*- coding:utf-8 -*- # 适配器模式 # 将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 # 应用场景:希望复用一些现存的类,但是接口又与复用环境要求不一致。 # 电压类 class Voltage(): def __init__(self, volt): self.standard = volt def Release(self): pass # 中国电压 class ChinaVoltage(Voltage): def __init__(self, volt): Voltage.__init__(self, volt) def ChinaRelease(self): print('中国释放电压%s' % self.standard) # 美国电压(待适配类) class USAVoltage(Voltage): def __init__(self, volt): Voltage.__init__(self, volt) def USARelease(self): print('美国释放电压%s' % self.standard) # 翻译(适配类) class Translator(Voltage): def __init__(self, volt): self.usaVoltage = USAVoltage(volt) def ChinaRelease(self): self.usaVoltage.USARelease() def clientUI(): # 在中国,中国的电压器可以通过函数ChinaRelease释放电压 c = ChinaVoltage('220V') c.ChinaRelease() # 在中国,美国的电压器无法通过函数ChinaRelease释放电压 # usa = USAVoltage('110V') # usa.ChinaRelease() # 解决方案:适配器 t = Translator('110V') t.ChinaRelease() if __name__ == '__main__': clientUI()
# 中国释放电压220V # 美国释放电压110V
二、具体实现:以国内篮球运动员的进攻防守与国外篮球运动员的进攻防守差异为例
第一步:创建一个抽象类--中国篮球运动员.有国内的进攻防守技能:attack和defense
class Player(): name = '' def __init__(self, name): self.name = name def Attack(self, name): pass def Defense(self): pass
第二步:创建三个具体类--国内的前锋、中锋、后卫:继承国内的进攻防守技能
# 前锋 class Forwards(Player): def __init__(self, name): Player.__init__(self, name) def Attack(self): printInfo("前锋%s 进攻" % self.name) def Defense(self, name): printInfo("前锋%s 防守" % self.name)
# 中锋(目标类) class Center(Player): def __init__(self, name): Player.__init__(self, name) def Attack(self): printInfo("中锋%s 进攻" % self.name) def Defense(self): printInfo("中锋%s 防守" % self.name)
# 后卫 class Guards(Player): def __init__(self, name): Player.__init__(self, name) def Attack(self): printInfo("后卫%s 进攻" % self.name) def Defense(self): printInfo("后卫%s 防守" % self.name)
第三步:创建一个具体类--外国的中锋.有外国的进攻防守技能:ForeignAttack和ForeignDefense
# 外籍中锋(待适配类) # 中锋 class ForeignCenter(Player): name = '' def __init__(self, name): Player.__init__(self, name) def ForeignAttack(self): printInfo("外籍中锋%s 进攻" % self.name) def ForeignDefense(self): printInfo("外籍中锋%s 防守" % self.name)
第四步:创建一个具体类--翻译(适配器).将外国中锋的技能转化为中国的技能,即将ForeignAttack转换成Attack
# 翻译(适配类) class Translator(Player): foreignCenter = None def __init__(self, name): self.foreignCenter = ForeignCenter(name) def Attack(self): self.foreignCenter.ForeignAttack() def Defense(self): self.foreignCenter.ForeignDefense()
第五步:实现
ef clientUI(): b = Forwards('巴蒂尔') m = Guards('姚明') ym = Translator('麦克格雷迪') b.Attack() m.Defense() ym.Attack() ym.Defense() return if __name__ == '__main__': clientUI()
输出结果
# 前锋巴蒂尔 进攻 # 后卫姚明 防守 # 外籍中锋麦克格雷迪 进攻 # 外籍中锋麦克格雷迪 防守
三、适配器模式的优缺点和使用场景
优点: 1、可以让任何两个没有关联的类一起运行。 2、提高了类的复用。 3、增加了类的透明度。 4、灵活性好。
缺点: 1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
使用场景:有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。
注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。

浙公网安备 33010602011771号