目录
1、设计模式简介
2、⭐设计模式分类
3、⭐单例模式有哪几种实现
4、代理模式与其实现方式
设计模式(Design Pattern)是一套被广泛接受并被证明有效的面向对象软件设计的指导原则和经验总结。它们提供了解决常见软件设计问题的通用解决方案,并促进代码的可重用性、可维护性和灵活性。简言之,就是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,是软件工程的基石脉络,如同大厦的结构一样。
设计模式可以帮助开发人员在软件开发过程中面对各种设计问题时,从经验丰富的设计实践中快速找到解决方案。这些模式描述了在不同情境下的问题和解决方案,并提供了一种共享的设计词汇,使得开发人员更容易进行沟通和交流。
通常分为三大类,共 23 种:
1. 创建型模式(Creational Patterns):这些模式关注对象的创建机制,旨在通过提供灵活的对象创建方式来降低系统的耦合度。
常见的创建型模式包括单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式等。
2. 结构型模式(Structural Patterns):这些模式关注对象之间的组合关系,旨在定义对象之间的协作方式,以实现更大的结构或功能。
常见的结构型模式包括适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式等。
3. 行为型模式(Behavioral Patterns):这些模式关注对象之间的通信和交互方式,旨在定义对象之间的责任分配和算法封装。
常见的行为型模式包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供全局访问点。
以下是几种常见的单例模式实现方式:
1. 懒汉式(Lazy Initialization):
在使用时才进行初始化,即懒加载,只在第一次使用的时候调用,一定程度上节省了资源。但第一次加载需要进行及时实例化,反应稍慢,而且每次调用getInstance都进行同步,造成不必要的同步开销。
- 线程不安全:在首次调用getInstance()方法时创建实例。如果多个线程同时调用该方法,在未创建实例之前可能会创建多个实例。
- 线程安全:在getInstance()方法上加锁,使用synchronized关键字或者使用双重检查锁定(Double-Checked Locking),确保在多线程环境下只创建一个实例。但是加锁会引入额外的开销。
2. 饿汉式(Eager Initialization):
- 在类加载时就创建好实例对象,保证了实例的唯一性和线程安全性。但是在程序启动时就创建实例,可能会造成内存资源浪费。加载速度快,实现简单,执行效率高,线程安全。
3. 静态内部类:
在类内部有一个静态内部类,既能确保线程安全,也能够保证单例对象的唯一性,同时也延迟了单例的实例化。但无法传参。
- 利用类的静态内部类特性实现延迟加载。在访问getInstance()方法时才会加载内部类,从而创建实例。通过JVM的类加载机制保证了线程安全性。
4. 枚举(Enum):
利用枚举的特性,让JVM来帮我们保证线程安全和单一实例的问题。
- 枚举类型保证了实例的唯一性和线程安全性。枚举类型的实例是在枚举类被加载时创建的,且枚举类的构造函数只会被调用一次。
每种实现方式都有其优缺点,开发人员可以根据具体的需求和场景选择适合的单例模式实现。需要注意的是,在多线程环境下,要考虑实现方式的线程安全性。
代理模式是一种结构型设计模式,它允许通过创建一个代理对象来控制对另一个对象的访问。代理对象与原始对象具有相同的接口,客户端无需知道实际的对象,通过代理对象间接地访问目标对象。
代理模式的实现方式通常涉及以下几个角色:
1. 抽象主题(Subject):定义了代理对象和真实对象的共同接口,客户端通过该接口访问真实对象。
2. 真实主题(Real Subject):实现了抽象主题接口,是代理对象所代表的真实对象,执行实际的业务逻辑。
3. 代理(Proxy):实现了抽象主题接口,并持有一个真实主题的引用,可以在客户端和真实主题之间进行控制和协调。在代理对象中可以添加一些额外的逻辑,如权限控制、缓存等。
代理模式的实现方式有多种,常见的包括:
1. 静态代理:
- 在编译时就已经确定代理类和真实类的关系,代理类与真实类实现相同的接口或继承相同的抽象类。
- 代理类持有真实类的引用,在代理方法中调用真实类的方法,并可以在调用前后添加额外的逻辑。
2. 动态代理:
- 在运行时生成代理类,不需要事先编写代理类。Java提供了动态代理的机制,主要利用了反射和InvocationHandler接口。
- 通过Proxy类和InvocationHandler接口可以动态地创建代理类,并在代理方法中调用真实对象的方法。
代理模式可以应用于很多场景,如远程代理、虚拟代理、保护代理等。它可以提供额外的功能、控制访问权限、实现延迟加载等,同时也能帮助降低系统的耦合度。
小结
每个设计模式都有其特定的用途和适用场景,开发人员可以根据具体需求选择合适的模式应用于设计和实现中。设计模式不是固定的规则,而是一种通用的指导原则,开发人员可以根据实际情况进行灵活的运用。