广东省建设信息网站成绩查询,长沙百度推广开户,南宁美容网站建设,西安市政道桥建设公司网站软件设计模式#xff08;Software Design Pattern#xff09;#xff0c;又称设计模式#xff0c;是一套被反复使用、多数人知晓 的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题#xff0c; 以及该问题的解决方案。也就是说Software Design Pattern又称设计模式是一套被反复使用、多数人知晓 的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题 以及该问题的解决方案。也就是说它是解决特定问题的一系列套路是前辈们的代码设计经验的总 结具有一定的普遍性可以反复使用。
本文章将讲解几种常见的设计模式
目录
一.单例模式
二.工厂模式
1.简单工厂模式
2.工厂方法模式
3.抽象工厂模式
4.工厂模式总结
三.代理模式
1.静态代理
2.JDK动态代理
3.CGLIB动态代理
4.代理模式总结
四.适配器模式
1.类适配器模式
2.对象适配器模式
3.接口适配器模式
4.适配器模式总结 一.单例模式
作为最常见的一种设计模式,单独写了一篇博客来介绍它
详情可参考最常考的设计模式之一---单例模式-CSDN博客 二.工厂模式
1.简单工厂模式
简单工厂模式是一种创建型设计模式它提供了一种创建对象的最简单方式通过将创建对象的逻辑封装在一个单独的类中而不暴露具体实例化的逻辑给调用方。简单工厂模式通常由一个工厂类来负责根据传入的参数来决定创建哪种具体的产品类的实例。
简单工厂模式包含以下角色 产品接口Product Interface定义了工厂创建的所有对象的通用接口。它可以是抽象类或者接口规定了产品对象的通用行为。 具体产品Concrete Products实现产品接口的具体类是简单工厂模式创建的对象。 工厂类Factory Class负责根据客户端的需求来创建具体产品的对象。它通常包含一个方法根据输入的参数来实例化具体产品对象。
示例如下:
1)创建图形的接口Shape和图形的具体实现类Circle和Square
//图形的接口(图形的标准)
public interface Shape {void draw();
}//具体实现类Circle
public class Circle implements Shape{Overridepublic void draw() {System.out.println(画一个圆圈);}
}//具体实现类Square
public class Square implements Shape{Overridepublic void draw() {System.out.println(画一个正方形);}
}2)创建提供对象的工厂类ShapeFactory
public class ShapeFactory {//根据输入参数创建对应的对象public Shape createShape(String shapeType){if(shapeType.equals(circle)){return new Circle();}else if(shapeType.equals(square)){return new Square();}else {return null;}}
}3)在客户端即可创建工厂类来获取想要的对象
public class Client {public static void main(String[] args) {ShapeFactory shapeFactorynew ShapeFactory();Shape circle shapeFactory.createShape(circle);circle.draw();Shape square shapeFactory.createShape(square);square.draw();}
}//运行结果画一个圆圈
画一个正方形Process finished with exit code 0简单工厂模式的优点包括
封装了对象的创建过程使得客户端不需要知道具体的实现细节。通过工厂类可以更灵活地管理对象的创建过程符合开闭原则当需要添加新的产品时只需要修改工厂类而不需要修改客户端代码。简化了客户端的调用只需要与工厂类进行交互不需要直接依赖具体的产品类。
然而简单工厂模式也有一些缺点
违反了单一职责原则因为工厂类不仅负责对象的创建还负责决定创建哪种对象。当产品类型较多时工厂类可能会变得臃肿难以维护和扩展。因为工厂类是静态的所以无法通过继承来改变创建方法的行为。 2.工厂方法模式
工厂方法模式Factory Method Pattern是一种创建型设计模式它通过定义一个用于创建对象的接口但是让子类决定实例化哪个类。这样工厂方法模式允许一个类在运行时创建它所需的具体对象而不是在设计时就指定。
工厂方法模式包含以下角色 产品接口Product Interface定义了工厂方法模式创建的所有对象的通用接口。它可以是抽象类或者接口规定了产品对象的通用行为。 具体产品Concrete Products实现产品接口的具体类是工厂方法模式创建的对象。 工厂接口Factory Interface定义了一个用于创建产品对象的接口可以是抽象类或者接口。它包含一个抽象的工厂方法子类通过实现这个方法来创建具体的产品对象。 具体工厂Concrete Factory实现工厂接口负责创建具体的产品对象。每个具体工厂对应创建一个具体产品对象。
示例如下:
1)创建图形的接口Shape和图形的具体实现类Circle和Square
//图形的接口(图形的标准)
public interface Shape {void draw();
}//具体实现类Circle
public class Circle implements Shape{Overridepublic void draw() {System.out.println(画一个圆圈);}
}//具体实现类Square
public class Square implements Shape{Overridepublic void draw() {System.out.println(画一个正方形);}
}2)创建工厂接口和对应的工厂实例
//工厂接口
public interface ShapeFactory {Shape createShape();
}//圆圈工厂实类
public class CircleFactory implements ShapeFactory{Overridepublic Shape createShape() {return new Circle();}
}//正方形工厂实类
public class SquareFactory implements ShapeFactory{Overridepublic Shape createShape() {return new Square();}
}3)在客户端即可创建对应的工厂类来获取想要的对象
public class Client {public static void main(String[] args) {//获取圆圈工厂ShapeFactory circleFactorynew CircleFactory();Shape circle circleFactory.createShape();circle.draw();//获取正方形工厂ShapeFactory squareFactorynew SquareFactory();Shape square squareFactory.createShape();square.draw();}
}//运行结果:画一个圆圈
画一个正方形Process finished with exit code 0工厂方法模式的核心思想是将对象的创建延迟到子类中去完成使得核心类只负责定义创建对象的接口而不负责创建对象的过程这样可以更好地符合开闭原则使得系统更加灵活可扩展。
工厂方法模式的优点包括
将对象的创建和使用分离降低了系统的耦合度。符合开闭原则当需要添加新的产品时只需要添加对应的具体产品类和具体工厂类不需要修改已有的代码。可以通过增加新的具体工厂来扩展系统而无需修改现有的客户端代码。
然而工厂方法模式也有一些缺点
每增加一个新的产品都需要编写一个新的具体产品类和对应的具体工厂类导致类的数量增加。客户端需要知道所使用的具体工厂类增加了系统的复杂度。 3.抽象工厂模式
抽象工厂模式是一种创建型设计模式它提供了一个接口用于创建一系列相关或相互依赖的对象而无需指定其具体类。抽象工厂模式是工厂方法模式的升级版它通过引入一个抽象工厂接口和多个具体工厂类来实现每个具体工厂类负责创建一组相关的产品。
抽象工厂模式包含以下角色 抽象工厂Abstract Factory声明用于创建一系列产品的抽象工厂接口。通常包含多个创建产品的抽象方法每个方法用于创建不同类型的产品。 具体工厂Concrete Factory实现抽象工厂接口负责创建具体类型的产品。每个具体工厂类对应一组相关的产品。 抽象产品Abstract Product声明了一类产品的接口是具体产品的抽象。 具体产品Concrete Product实现了抽象产品接口是工厂生产的具体产品实例。
示例如下:
1)创建两个产品族:小米小米空调、小米手机和华为华为空调、华为手机
//空调定义接口
public interface Air {void takeAir();
}//华为空调
public class HuaWeiAir implements Air{Overridepublic void takeAir() {System.out.println(展示一台华为空调);}
}//小米空调
public class XiaoMiAir implements Air{Overridepublic void takeAir() {System.out.println(展示一台小米空调);}
}//手机定义接口
public interface Phone {void takePhone();
}//华为手机
public class HuaWeiPhone implements Phone{Overridepublic void takePhone() {System.out.println(展示一台华为手机);}
}//小米手机
public class XiaoMiPhone implements Phone{Overridepublic void takePhone() {System.out.println(展示一台小米手机);}
}
2)创建抽象工厂和对应的具体工厂
//抽象工厂定义
public interface AbstractFactory {Phone getPhone();Air getAir();}//小米工厂
public class XiaoMiFactory implements AbstractFactory{Overridepublic Phone getPhone() {return new XiaoMiPhone();}Overridepublic Air getAir() {return new XiaoMiAir();}
}//华为工厂
public class HuaWeiFactory implements AbstractFactory{Overridepublic Phone getPhone() {return new HuaWeiPhone();}Overridepublic Air getAir() {return new HuaWeiAir();}
}
3)在客户端即可创建对应的工厂类来获取想要的对象
public class Client {public static void main(String[] args) {//创建华为工厂AbstractFactory huaWeiFactorynew HuaWeiFactory();//展示华为产品Air huaWeiAir huaWeiFactory.getAir();huaWeiAir.takeAir();Phone huaWeiPhone huaWeiFactory.getPhone();huaWeiPhone.takePhone();//创建小米工厂AbstractFactory xiaoMiFactorynew XiaoMiFactory();//展示小米产品Air xiaoMiAir xiaoMiFactory.getAir();xiaoMiAir.takeAir();Phone xiaoMiiPhone xiaoMiFactory.getPhone();xiaoMiiPhone.takePhone();}
}//运行结果展示:展示一台华为空调
展示一台华为手机
展示一台小米空调
展示一台小米手机Process finished with exit code 0抽象工厂模式的优点包括 它将产品的创建与客户端分离客户端不需要知道具体产品的类名只需要通过抽象接口来操作产品从而降低了客户端与具体产品类之间的耦合。 它能够确保创建的产品是相互兼容的因为每个具体工厂类都负责创建一组相关的产品这些产品之间有一定的关联性。
然而抽象工厂模式也存在一些缺点 新增产品族比较困难因为需要修改抽象工厂接口和所有的具体工厂类。 类的数量随着产品族的增加而增加导致系统变得更加复杂。
4.工厂模式总结 简单工厂模式 特点由一个工厂类根据传入的参数决定创建哪一种产品类的实例。优点结构简单适用于创建对象的场景较少。缺点违反了开闭原则每次添加新产品都需要修改工厂类的代码。 工厂方法模式 特点定义一个创建对象的接口让子类决定实例化哪个类。优点符合开闭原则每个具体工厂类只负责创建对应的产品。缺点会导致类的数量增加系统结构复杂。 抽象工厂模式 特点提供一个接口用于创建相关或依赖对象的家族而不需要明确指定具体类。优点可以创建一组相关的产品对象符合开闭原则。缺点难以支持新种类的产品如果需要添加新产品族需要修改接口及所有实现类。
总的来说简单工厂模式适用于对象的创建逻辑较为简单且不会频繁变动的场景工厂方法模式适用于需要创建一类产品的场景不同的产品由不同的工厂类来创建抽象工厂模式适用于需要创建一组相关对象的场景且系统需要支持多个产品族的情况。选择合适的工厂模式取决于具体的需求和系统设计 三.代理模式
代理模式是一种结构型设计模式它允许你提供一个代理类控制对其他对象的访问。代理模式通常用于管理访问对象的方式以在访问对象时添加额外的功能或者控制对对象的访问权限。
代理模式涉及以下几个角色 抽象主题Subject定义了代理类和真实主题被代理的对象的共同接口客户端通过这个接口访问真实主题和代理类。 真实主题Real Subject定义了真实对象的类代理类通过调用真实主题来完成实际的操作。 代理Proxy提供了与真实主题相同的接口持有对真实主题的引用并负责在调用真实主题之前或之后执行额外的操作。
1.静态代理
静态代理是代理模式的一种形式在编译期间就已经确定代理类和真实主题之间的关系代理类在编译期间就确定了对哪个真实主题进行代理。在静态代理中代理类和真实主题都实现了相同的接口或继承了相同的父类客户端通过调用代理类来访问真实主题。
示例如下:
1)创建File接口类和对应的实体类ReadFile
//接口
public interface File {void read();
}//实体类
public class ReadFile implements File{String fileName;public ReadFile(String fileName){this.fileNamefileName;}Overridepublic void read() {System.out.println(正在阅读文件:fileName);}
}
2)创建代理类ProxyFile来代理FileRead
public class ProxyFile implements File{ReadFile readFile;public ProxyFile(String fileName){readFile new ReadFile(fileName);}Overridepublic void read() {System.out.println(代理类调用readFile:);readFile.read();}
}
3)在客户端创建代理类来执行功能
public class Client {public static void main(String[] args) {//直接创建ReadFile类ReadFile readFilenew ReadFile(一个文件);readFile.read();System.out.println(-------------------);//创建ReadFile的代理类ProxyFile proxyFilenew ProxyFile(一个文件);proxyFile.read();}
}//执行结果:正在阅读文件:一个文件
-------------------
代理类调用readFile:
正在阅读文件:一个文件Process finished with exit code 0静态代理的优点包括 简单易懂静态代理在编译期间就确定了代理类和真实主题之间的关系因此易于理解和实现。 编译期检查由于在编译期间就确定了代理类和真实主题之间的关系因此可以在编译期间进行类型检查。 降低耦合度客户端只需与代理类进行交互而不需要直接与真实主题进行交互降低了客户端和真实对象之间的耦合度。
静态代理的缺点包括 增加了代码量每个真实主题都需要对应一个代理类如果有多个真实主题就需要编写多个代理类增加了代码量。 灵活性差在编译期间确定了代理类和真实主题之间的关系因此缺乏灵活性不能动态地改变代理对象。 2.JDK动态代理
动态代理是Java语言提供的一种机制允许在运行时动态创建代理类和对象而不需要事先编写代理类的代码 动态代理涉及以下几个主要角色 代理接口Proxy Interface定义了代理类和真实主题类共同的接口。 真实主题类Real Subject Class实现了代理接口的类也称为委托类。 调用处理器Invocation Handler实现了java.lang.reflect.InvocationHandler接口的类包含了实际的代理逻辑当客户端调用代理对象的方法时最终会由调用处理器来处理。 代理工厂Proxy Factory用于动态创建代理对象的工厂类。
示例如下:
1)创建要代理的接口SellCoffee和实现接口的具体类CoffeeShop
//要代理的接口
public interface SellCoffee {void sell();
}//实现的具体类
public class CoffeeShop implements SellCoffee{Overridepublic void sell() {System.out.println(卖出一杯咖啡);}
}
2)实现代理工厂(代理工厂可以创建代理类)
public class CoffeeFactory {private CoffeeShop coffeeShop new CoffeeShop();public SellCoffee getCoffeeProxy(){SellCoffee sellCoffee(SellCoffee) Proxy.newProxyInstance(coffeeShop.getClass().getClassLoader(),coffeeShop.getClass().getInterfaces(), new InvocationHandler() {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(JDK动态代理创建代理类实现功能:);Object objmethod.invoke(coffeeShop,args);return obj;}});return sellCoffee;}}
3)在客户端中调用代理工厂类(调用处理器)获得代理类
public class Client {public static void main(String[] args) {CoffeeFactory coffeeFactorynew CoffeeFactory();SellCoffee proxycoffeeFactory.getCoffeeProxy();proxy.sell();}
}//运行结果:JDK动态代理创建代理类实现功能:
卖出一杯咖啡Process finished with exit code 0Java动态代理的特点包括 运行时创建代理类和代理对象是在运行时动态创建的而不是在编译时确定的。 基于接口Java动态代理是基于接口的代理也就是代理类和真实主题类都要实现同一个接口。 灵活性由于代理类和代理对象是在运行时创建的因此具有更大的灵活性能够根据需要动态创建不同的代理对象。 简化开发相比较静态代理动态代理能够减少手动编写代理类的工作提高开发效率 3.CGLIB动态代理
CGLIBCode Generation Library是一个功能强大的高性能的代码生成库用于在运行时扩展Java类和实现动态代理。与Java动态代理相比CGLIB 动态代理不要求被代理的类实现接口而是通过生成被代理类的子类来实现代理因此也被称为子类代理。
CGLIB 动态代理的原理是在内存中动态构建一个子类覆盖被代理类中的方法从而实现对被代理类的增强。当客户端调用代理对象的方法时实际上是调用了子类中的方法这些方法会在调用被代理类的方法前后执行额外的逻辑比如记录日志、权限验证、性能监控等。
示例如下:
1)创建要代理类CoffeeShop //要代理的类
public class CoffeeShop {public void sell() {System.out.println(卖出一杯咖啡);}
}
2)创建代理工厂类
public class CoffeeFactory implements MethodInterceptor{private CoffeeShop coffeeShop new CoffeeShop();public CoffeeShop getProxyObject() {//创建Enhancer对象类似于JDK动态代理的Proxy类下一步就是设置几个参数Enhancer enhancer new Enhancer();//设置父类的字节码对象enhancer.setSuperclass(coffeeShop.getClass());//设置回调函数enhancer.setCallback(this);//创建代理对象CoffeeShop obj (CoffeeShop) enhancer.create();return obj;}/*intercept方法参数说明o 代理对象method 真实对象中的方法的Method实例args 实际参数methodProxy 代理对象中的方法的method实例*/public CoffeeShop intercept(Object o, Method method, Object[] args,MethodProxy methodProxy) throws Throwable {System.out.println(CGLIB动态代理创建代理类实现功能:);CoffeeShop result (TrainStation) methodProxy.invokeSuper(o,args);return result;}
}3)在客户端中调用代理工厂类(调用处理器)获得代理类
public class Client {public static void main(String[] args) {//创建代理工厂对象CoffeeFactory factory new CoffeeFactory();//获取代理对象CoffeeShop proxyObject factory.getProxyObject();proxyObject.sell();}
}CGLIB 动态代理的特点包括 基于继承CGLIB 动态代理是基于继承的代理它通过生成被代理类的子类来实现代理。 无需接口与 Java 动态代理不同CGLIB 动态代理不要求被代理类实现接口可以代理任何类包括 final 类。 性能高由于生成的代理类是被代理类的子类因此方法调用会更快性能较高。
CGLIB 动态代理通常需要使用第三方库例如 Spring 框架中就广泛使用了 CGLIB 动态代理来实现 AOPAspect-Oriented Programming面向切面编程。
4.代理模式总结 静态代理 结构在编译时就已经确定代理类和被代理类的关系。特点代理类和被代理类是早已存在的代理类需要显式地实现与被代理类相同的接口或继承相同的父类。优点结构简单易于理解和实现。缺点如果需要代理多个类会导致代理类的数量增加不利于代码的维护。 动态代理 结构在运行时生成代理类无需在编码时就知道代理关系。特点代理类在运行时动态生成不需要显式地实现与被代理类相同的接口或继承相同的父类。优点可以减少代理类的数量对系统的扩展性和维护性更好。缺点实现相对复杂需要使用反射等技术性能方面可能会有一定影响。 四.适配器模式
适配器模式Adapter Pattern是一种结构型设计模式它允许将一个类的接口转换成客户端所期望的另一个接口。这种模式通常用于使原本不兼容的接口能够一起工作或者将已有的类集成到某个系统中而不需要修改原有类的代码。
1.类适配器模式
类适配器模式通过多重继承来实现适配器与被适配者之间的关系。在类适配器模式中适配器类继承了被适配者类并实现了目标接口从而使得适配器可以调用被适配者的方法并且将其转换为客户端所期待的接口。
下面是类适配器模式中的几个关键角色 目标接口Target客户端所期待的接口适配器类通过实现这个接口来与客户端进行交互。 适配器Adapter适配器类继承了被适配者类并实现了目标接口从而使得适配器可以调用被适配者的方法并且将其转换为客户端所期待的接口。 被适配者Adaptee被适配者是客户端已有的类它的接口与目标接口不兼容。
示例如下:
假设有一个旧的音频播放器类 OldAudioPlayer它有一个 playAudio 方法用于播放音频但它的接口与我们现在的音频播放器接口 AudioPlayer 不兼容。我们想要通过适配器模式来使得 OldAudioPlayer 能够适配到 AudioPlayer 接口。
1)定义目标接口 AudioPlayer和旧的音频播放器类 OldAudioPlayer
// 目标接口
public interface AudioPlayer {void play();}// 旧的音频播放器类
public class OldAudioPlayer {public void playAudio() {System.out.println(老播放器播放音乐);}}
2)创建一个适配器类 AudioPlayerAdapter 来适配 OldAudioPlayer 到 AudioPlayer 接口 // 适配器类
public class AudioPlayerAdapter extends OldAudioPlayer implements AudioPlayer{Overridepublic void play() {//继承OldAudioPlayer类,就可以调用旧的播放音频方法playAudio();}
}3)在客户端通过适配器类调用 play 方法来播放音频而不需要直接调用 OldAudioPlayer 中的 playAudio 方法
public class Main {public static void main(String[] args) {// 创建适配器AudioPlayer adapter new AudioPlayerAdapter();// 调用适配器的 play 方法实际上会调用 OldAudioPlayer 中的 playAudio 方法adapter.play();}
}//运行结果老播放器播放音乐Process finished with exit code 0类适配器模式的工作原理如下
适配器类继承了被适配者类并实现了目标接口。适配器类中包含了一个被适配者对象的引用。在适配器类中通过调用被适配者对象的方法来实现目标接口中的方法。
类适配器模式的优点包括
结构简单类适配器模式只需要一个适配器类即可实现适配器与被适配者之间的关系结构相对简单。单一职责原则适配器类既充当了适配器的角色又充当了被适配者的角色符合单一职责原则。
但类适配器模式也有一些缺点
只能适配一个类由于类适配器模式使用了继承关系因此适配器类只能适配一个具体的被适配者类不够灵活。不支持被适配者子类的适配如果被适配者类存在子类并且想要适配子类的方法需要重写适配器类的相应方法增加了系统的复杂性。
2.对象适配器模式
对象适配器模式用于使一个类的接口与另一个类的接口兼容。在对象适配器模式中适配器类持有要适配的类的实例并实现目标接口从而将客户端对目标接口的调用转发给被适配的对象。
以下是对象适配器的主要参与者及其角色 目标接口Target定义客户端使用的特定领域的接口。 适配器Adapter实现目标接口并持有要适配的类的实例在实现目标接口的方法中调用被适配对象的方法完成适配工作。 被适配对象Adaptee需要被适配的类其接口与目标接口不兼容。
示例如下:
假设有一个音频播放器AudioPlayer它有一个播放方法play(String audioType, String fileName)可以播放不同类型的音频文件。目前支持的音频类型有MP3和MP4。
现在我们希望能够播放其他格式的音频文件比如VLC格式的文件。但是VLC格式的播放器接口与我们的播放器接口不兼容这时候就可以使用对象适配器模式来解决这个问题。
1)定义接口MediaPlayer定义了播放器的基本操作和实现了MediaPlayer接口的AudioPlayer类
//接口MediaPlayer
public interface MediaPlayer {void play(String audioType, String fileName);
}//播放器类
public class AudioPlayer implements MediaPlayer {public void play(String audioType, String fileName) {// 播放MP3文件的逻辑if (audioType.equalsIgnoreCase(mp3)) {System.out.println(Playing MP3 file: fileName);}// 播放MP4文件的逻辑else if (audioType.equalsIgnoreCase(mp4)) {System.out.println(Playing MP4 file: fileName);}}
}2)定义新的接口AdvancedMediaPlayer和实现了其接口的VlcPlayer类 public interface AdvancedMediaPlayer {void playVlc(String fileName);}public class VlcPlayer implements AdvancedMediaPlayer {public void playVlc(String fileName) {System.out.println(Playing VLC file: fileName);}}
3)创建适配器类MediaAdapter实现目标接口MediaPlayer并持有AdvancedMediaPlayer的实例
public class MediaAdapter implements MediaPlayer {private AdvancedMediaPlayer advancedMusicPlayer;public MediaAdapter(String audioType){if(audioType.equalsIgnoreCase(vlc) ){advancedMusicPlayer new VlcPlayer();}}public void play(String audioType, String fileName) {if(audioType.equalsIgnoreCase(vlc)){advancedMusicPlayer.playVlc(fileName);}}
}
4)在客户端使用适配器来播放VLC格式的音频文件
public class Client {public static void main(String[] args) {AudioPlayer audioPlayer new AudioPlayer();audioPlayer.play(mp3, song.mp3);audioPlayer.play(mp4, movie.mp4);MediaPlayer mediaAdapter new MediaAdapter(vlc);mediaAdapter.play(vlc, vlc_song.vlc);}
}对象适配器模式的优点包括
可以将不兼容的接口协调起来使得原本不能一起工作的类可以协同工作。通过适配器可以使系统更灵活减少代码修改和耦合度。
然而对象适配器模式也存在一些限制
适配器需要实例化被适配对象可能会增加系统复杂性。对象适配器模式可能涉及多层嵌套导致代码结构相对复杂。
3.接口适配器模式
接口适配器模式Interface Adapter Pattern允许一个类通过多个接口与其他类进行通信。这种模式通过引入一个抽象类作为适配器接口适配器该抽象类实现了目标接口并且其中的方法都是空方法被适配类只需要实现自己感兴趣的方法即可。
比较简单就不作示例了
4.适配器模式总结 类适配器模式 结构类适配器模式使用继承来实现适配器。适配器类同时继承目标接口和被适配类从而可以将目标接口的调用转发到被适配类。优点结构相对简单适配器与被适配类之间的关系更为明确。缺点如果适配器需要适配多个被适配类会导致多重继承语言限制的问题。 对象适配器模式 结构对象适配器模式使用组合持有被适配对象的实例来实现适配器。适配器类实现目标接口并持有被适配类的实例在实现目标接口的方法中调用被适配对象的方法。优点可以适配多个被适配类避免了多重继承的问题。缺点需要实例化被适配对象的实例可能增加系统复杂性。 接口适配器模式 结构接口适配器模式通过引入一个抽象类作为适配器该抽象类实现了目标接口并且其中的方法都是空方法被适配类只需要实现自己感兴趣的方法即可。优点可以灵活地选择需要适配的方法避免了类适配器和对象适配器中需要实现所有方法的问题。缺点引入了额外的抽象类可能增加系统复杂性。 到这里常见的设计模式就介绍完了~