8.Java设计模式学习笔记(工厂,单例,适配器,装饰器,代理,中介者)

本文详细介绍了Java设计模式中的六种模式:适配器模式用于接口转换,工厂模式简化产品创建,装饰器模式动态增加功能,代理模式提供额外服务,中介者模式降低对象间耦合,单例模式确保类只有一个实例。文章探讨了每种模式的优缺点和应用场景,如Java I/O中的适配器模式,以及Spring AOP中的代理模式应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

适配器模式(适配器的作用就是将一个接口适配到另一个接口)结构型模式

对适配器模式的功能很好理解,就是把一个类的接口变换成客户端所能接受的另一种接口,从而使两个接口不匹配而无法在一起工作的两个类能够在一起工作。
类适配器
类适配器的优点:
1、由于适配器类是适配者类的子类,因此可以再适配器类中置换一些适配者的方法,使得适配器的灵活性更强。
类适配器的缺点:
1、对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为接口,不能为类,其使用有一定的局限性,不能将一个适配者类和他的子类同时适配到目标接口。
对象适配器
对象适配器的优点:
1、把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和他的子类都适配到目标接口。
对象适配器的缺点:
1、与类适配器模式相比,要想置换适配者类的方法就不容易。

Target(目标接口USB)
adapter(实现了USB接口,有接口的方法,同时继承了一个耳机类(adaptee))//类适配器
Adapter(实现了USB接口,有接口的方法,在适配器里面加载了耳机的一个对象(adaptee))//对象适配器
运用场景:
旧系统的改造和升级

JAVA的IO类库中有很多这样的需求,如将字符串数据转变成字节数据保存到文件中,将字节数据转变成流数据等

Java I/O中的适配模式

InputStreamReader继承了Reader抽象类并实现,且持有了InputStream的引用,这里是通过StreamDecoder类间接持有的,因为从byte到char要经过编码。
很显然,适配器就是InputStreamReader,源角色就是InputStream代表的实例对象,目标接口就是Reader类。OutputStreamWriter 也类似。
在I.O类库中还有很多类似的用法,如StringReader将一个string类适配到Reader接口,ByteArrayInputStream适配器将byte数组适配到InputStream流接口处理。

工厂模式(用户只需要产品不需要知道生产过程) 创建型模式

1.简单工厂的定义:提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类(通过一个工厂生产不同的产品)要增加功能的话就要修改代码,所以不好(开闭原则)
2.工厂方法的定义:不同品牌的产品要到不同的工厂里面生产,但是会有很多工厂,增加了用户的操作复杂度。
3.抽象工厂:共同有一个抽象的工厂,不同的工厂都继承了抽象工厂,在这些工厂中需要有一个默认工厂(用户只要与默认工厂打交道),默认工厂通过用户给的需求,调用不同的工厂,生产产品。
代理模式(代理模式是将原类进行封装,客户端只需要与代理进行交流。代理就是原类的一个替身。简而言之就是用一个对象代表另外一个对象。强调的是个体。)
结构型模式(维护升级系统)
代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务。

  1. 静态代理:静态代理是由程序员创建或特定工具自动生成源代码,在对其编译。在程序员运行之前,代理类.class文件就已经被创建了。
  2. 动态代理:动态代理是在程序运行时通过反射机制动态创建的。
    在动态代理中我们不再需要再手动的创建代理类,我们只需要编写一个动态处理器(实现implements InvocationHandler接口,实现接口的invoke方法,在这个方法里面就可以实现在方法调用前后处理事务)就可以了。
    Proxy.newProxyInstnce(1类加载器,2目标实现对象的接口,自己编写的
    3动态处理器)

优点 
• 降低了用户与对象直接的耦合度。
• 可以扩展具体的主题类或者主题类的功能,扩展性好。
缺点
• 由于增加了一个代理对象,导致请求速度变慢。
• 增加了系统的复杂性

用途:JDK动态代理与CGLib动态代理(在没有接口的时候,生产子类)均是实现Spring AOP的基础。
Spring中的aop实现
日志拦截
声明式事务处理
Mybatis中实现拦截器插件

装饰器模式

装饰者模式,顾名思义,就是将某个类重新装扮一下,使得它比原来更“漂亮”,或者在功能上更强大,这就是装饰器模式所要达到的目的。但是作为原来的这个类的使用者还不应该感受到装饰前与装饰后有什么不同,即用法不变,否则就破坏了原有类的结构了,所以装饰器模式要做到对被装饰类的使用者透明,这是对装饰器模式的一个基本要求。
职能:
动态的为一个对象增加新的功能
是一种代替了继承技术的技术(无需通过继承来增加子类,就增加功能,减少类的数量,但是会出现许多的小对象)

component (零件)公共接口:
抽象组件角色,定义一组抽象的接口,规定这个被装饰组件都有哪些功能(真实对象和装饰对象有相同的接口,这样的话就可以让客户端对象把装饰对象和真实对象用相同的方式交互)
concreteComponent:
(真实对象)实现这个抽象组件(component)的所有功能。
Decorator:
装饰器角色,它持有一个component真实对象实例的引用,定义一个与抽象组件一致的接口
ConcreteDecorator:
具体的装饰器实现者,负责实现装饰器角色定义的功能。

装饰器模式的作用就是赋予被装饰的类更多功能
JAVA IO 中的装饰器模式

前面介绍了装饰器模式的作用就是赋予被装饰的类更多功能,在java I/O 类库中有很多不同的功能组合情况,这些不同的功能组合都是使用了装饰器模式事项大的,下面以FilterInputStream为例介绍装饰器模式的使用。

InputeStream 类就是以抽象组件存在的:而FileInputStream就是具体组件,它实现了抽象组件的所有接口;FilterInputStream类无疑就是装饰角色,它实现了InputStream类的所有接口,并且持有InputStream的对象实例的引用; 

BufferedInputStream是具体的装饰器实现者,它给InputStream类附加了功能,这个装饰器类的作用就是使得InputStream读取的数据保存在内存中,而提高读取的性能。
适配器模式与装饰器模式的区别
装饰器与适配器都有一个别名叫做 包装模式(Wrapper),它们看似都是起到包装一个类或对象的作用,但是使用它们的目的很不一一样。适配器模式的意义是要将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的。 而装饰器模式不是要改变被装饰对象的接口,而是恰恰要保持原有的接口,但是增强原有对象的功能,或者改变原有对象的处理方式而提升性能。所以这两个模式设计的目的是不同的。

中介者模式

定义一个中介对象来封装系列对象之间的交互。中介者使各个对象不需要显示地相互引用,从而使其耦合性松散,而且可以独立地改变他们之间的交互
使用中介者模式的优点:
1.降低了系统对象之间的耦合性,使得对象易于独立的被复用。
2.提高系统的灵活性,使得系统易于扩展和维护。

使用中介者模式的缺点:
中介者模式的缺点是显而易见的,因为这个“中介“承担了较多的责任,所以一旦这个中介对象出现了问题,那么整个系统就会受到重大的影响。
中介者与代理模式的区别
1,中介者模式:A,B之间的对话通过C来传达。A,B可以互相不认识(减少了A和B对象间的耦合)
2,代理模式:A要送B礼物,A,B互相不认识,那么A可以找C来帮它实现送礼物的愿望(封装了A对象)

单例模式

在这里插入图片描述
在这里插入图片描述
饿汉式
在这里插入图片描述

懒汉式
在这里插入图片描述

枚举单例:
手写:

// 单例
public enum BeanContext {

Instance;
private BeanContext() {
    System.out.println("init");
}
public void print() {

    System.out.println("ffffffffffff");
}

//测试
public static void main(String[] args) {

    BeanContext b1 = BeanContext.Instance;
    b1.print();
    BeanContext b2 = BeanContext.Instance;
    b2.print();
    BeanContext b3 = BeanContext.Instance;
    b3.print();
    BeanContext b4 = BeanContext.Instance;
    b4.print();

}

打印结果中显示只打印了一次 “init”,说明只初始化了一次该对象;
回头想想,起始第一段代码已经说明了该枚举类本身就实现了单例,但是对枚举使用的比较少,没想明白是怎么回事。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值