适配器模式,它是一种结构型设计模式,它用于将一个类的接口转换成客户端所期待的另一种接口,使得原本因接口不兼容而无法一起工作的两个类能够协同工作。
适配器模式包括类适配器模式和对象适配器模式。类适配器模式依赖于继承关系实现,因此其耦合度较高。对象适配器模式则依赖于组合或聚合关系实现,因此其耦合度较低。
适配器模式的结构包括抽象原有接口、具体原有接口、抽象目标接口和适配器。适配器实现抽象目标接口,并实现目标接口的行为。
适配器模式包含以下三个角色:
1、源(Adaptee):需要被适配的对象或类型,相当于插头。
2、适配器(Adapter):连接目标和源的中间对象,相当于插头转换器。
3、目标(Target):期待得到的目标,相当于插座。
适配器模式的使用场景:
1、系统需要使用现有的类,但现有类的接口不符合系统的需要。
2、需要一个统一的输出接口,而输入类型不可预知。例如,在Android开发中的Adapter模式,用户的数据各式各样,但最终都是通过getView()返回一个View,这是适配器模式的一个很好的应用场景。
3、创建一个可以复用的类。例如,Android中的Adapter模式可以使得该类可以与其他不相关的类或不可预见的类协同工作。
适配器模式是一种结构型设计模式,它用于将一个类的接口转换成客户端所期待的另一种接口,使得原本因接口不兼容而无法一起工作的两个类能够协同工作。
适配器模式的创建步骤:
1、创建Target接口。这个接口定义了目标类需要实现的方法。
2、创建源类(Adaptee)。这个类中可能包含了一些需要适配的方法。
3、创建适配器类(Adapter)。该类继承自源类并实现目标接口。适配器类需要实现目标接口中定义的方法,并将源类的原有方法封装成符合目标接口要求的方法。
在适配器类中,我们需要将Target接口的方法和Adaptee类的方法进行适配。具体来说,我们需要将Target接口的方法调用转发到Adaptee类的方法上。
适配器模式的优点,主要包括:
1、更好的复用性:适配器模式允许系统使用已经存在的类,即使其接口不符合系统的需求,通过适配器模式可以解决不兼容的问题,使这些功能类得到复用。
2、增加类的透明性和复用性:适配器模式将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。
3、灵活性和扩展性:适配器模式通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。
适配器模式的缺点,主要包括:
1、增加系统的复杂性:适配器模式需要引入一个额外的适配器类,增加了系统的复杂性。
不适合大型系统:适配器模式会导致系统的结构变得复杂,并可能影响到系统的性能,因此不适合大型系统。
2、破坏封装性:适配器模式需要访问适配者的私有方法和属性,这会破坏适配者的封装性。
3、降低了代码的可读性和可维护性:由于适配器模式的使用需要额外的类和方法,这会使得代码更加复杂和难以理解,降低了代码的可读性和可维护性。

以下是一个示例,展示了如何在C#中实现适配器模式:
- using System;
-
- // 目标接口
- public interface Target
- {
- void Request();
- }
-
- // 源类
- public class Adaptee
- {
- public void SpecificRequest()
- {
- Console.WriteLine("Adaptee's specific request.");
- }
- }
-
- // 适配器类
- public class Adapter : Target
- {
- private Adaptee adaptee;
-
- public Adapter(Adaptee adaptee)
- {
- this.adaptee = adaptee;
- }
-
- public void Request()
- {
- adaptee.SpecificRequest();
- }
- }
-
- // 客户端类
- public class Client
- {
- public static void Main()
- {
- Adaptee adaptee = new Adaptee(); // 创建源类对象
- Target target = new Adapter(adaptee); // 创建适配器,并将源类对象传入适配器构造函数中进行适配
- target.Request(); // 客户端调用目标接口中的方法,实际上会调用适配器中的方法,适配器中会调用源类的方法
- }
- }
适配器模式通常通过以下方式实现:
- // 目标接口
- interface Target {
- void request();
- }
-
- // 源类
- class Adaptee {
- public void specificRequest() {
- System.out.println("Adaptee's specific request.");
- }
- }
-
- // 适配器类
- class Adapter implements Target {
- private Adaptee adaptee;
-
- public Adapter(Adaptee adaptee) {
- this.adaptee = adaptee;
- }
-
- public void request() {
- adaptee.specificRequest();
- }
- }
-
- // 客户端类
- class Client {
- public static void main(String[] args) {
- Adaptee adaptee = new Adaptee(); // 创建源类对象
- Target target = new Adapter(adaptee); // 创建适配器,并将源类对象传入适配器构造函数中进行适配
- target.request(); // 客户端调用目标接口中的方法,实际上会调用适配器中的方法,适配器中会调用源类的方法
- }
- }
在JavaScript中,适配器实现方式如下:
- // 目标接口
- interface Target {
- request();
- }
-
- // 源类
- class Adaptee {
- specificRequest() {
- console.log('Adaptee\'s specific request.');
- }
- }
-
- // 适配器类
- class Adapter implements Target {
- constructor(adaptee: Adaptee) {
- this.adaptee = adaptee;
- }
-
- request() {
- this.adaptee.specificRequest();
- }
- }
-
- // 客户端类
- class Client {
- static main() {
- const adaptee = new Adaptee(); // 创建源类对象
- const target = new Adapter(adaptee); // 创建适配器,并将源类对象传入适配器构造函数中进行适配
- target.request(); // 客户端调用目标接口中的方法,实际上会调用适配器中的方法,适配器中会调用源类的方法
- }
- }
以下是在C++中实现适配器模式:
- // 目标接口
- class Target {
- public:
- virtual void request() = 0;
- };
-
- // 源类
- class Adaptee {
- public:
- void specificRequest() {
- cout << "Adaptee's specific request." << endl;
- }
- };
-
- // 适配器类
- class Adapter : public Adaptee, public Target {
- public:
- void request() override {
- specificRequest();
- }
- };
-
- // 客户端类
- class Client {
- public:
- static void main() {
- Adaptee* adaptee = new Adaptee(); // 创建源类对象
- Target* target = new Adapter(adaptee); // 创建适配器,并将源类对象传入适配器构造函数中进行适配
- target->request(); // 客户端调用目标接口中的方法,实际上会调用适配器中的方法,适配器中会调用源类的方法
- }
- };
下面是一个简单的Python适配器模式示例:
- # 目标接口
- class Target:
- def request(self):
- pass
-
- # 源类
- class Adaptee:
- def specific_request(self):
- print("Adaptee's specific request.")
-
- # 适配器类
- class Adapter(Adaptee, Target):
- def request(self):
- self.specific_request()
-
- # 客户端类
- class Client:
- def main(self):
- adaptee = Adaptee() # 创建源类对象
- target = Adapter(adaptee) # 创建适配器,并将源类对象传入适配器构造函数中进行适配
- target.request() # 客户端调用目标接口中的方法,实际上会调用适配器中的方法,适配器中会调用源类的方法
-
- client = Client()
- client.main()
以下是一个示例,展示了如何在go中实现适配器模式:
- package main
-
- import "fmt"
-
- // 目标接口
- type Target interface {
- Request()
- }
-
- // 源类
- type Adaptee struct{}
-
- func (a *Adaptee) SpecificRequest() {
- fmt.Println("Adaptee's specific request.")
- }
-
- // 适配器类
- type Adapter struct {
- adaptee *Adaptee
- }
-
- func (a *Adapter) Request() {
- a.adaptee.SpecificRequest()
- }
-
- // 客户端类
- type Client struct{}
-
- func (c *Client) Main() {
- adaptee := &Adaptee{} // 创建源类对象
- target := &Adapter{adaptee: adaptee} // 创建适配器,并将源类对象传入适配器构造函数中进行适配
- target.Request() // 客户端调用目标接口中的方法,实际上会调用适配器中的方法,适配器中会调用源类的方法
- }
-
- func main() {
- client := &Client{} // 创建客户端对象
- client.Main() // 执行客户端的主要逻辑,完成适配器的使用示例
- }
以下是一个示例,展示了如何在PHP中实现适配器模式:
- interface Target {
- public function request();
- }
-
- class Adaptee {
- public function specificRequest() {
- echo "Adaptee's specific request.";
- }
- }
-
- class Adapter implements Target {
- private $adaptee;
-
- public function __construct(Adaptee $adaptee) {
- $this->adaptee = $adaptee;
- }
-
- public function request() {
- $this->adaptee->specificRequest();
- }
- }
-
- class Client {
- public function main() {
- $adaptee = new Adaptee(); // 创建源类对象
- $target = new Adapter($adaptee); // 创建适配器,并将源类对象传入适配器构造函数中进行适配
- $target->request(); // 客户端调用目标接口中的方法,实际上会调用适配器中的方法,适配器中会调用源类的方法
- }
- }
-
- $client = new Client();
- $client->main();
在上面的示例中,目标接口是Target,它定义了客户端所期待的接口。源类是Adaptee,它拥有原本的接口,但不符合目标接口。适配器类是Adapter,它实现目标接口并封装源类的原有方法。客户端类是Client,它通过调用目标接口中定义的方法来调用适配器类的方法。适配器的内部会自动调用源类的方法,实现了源类和目标接口的适配。
《完结》