设计模式
单例模式
单例模式(Singleton Pattern)它确保一个类只有一个实例,并提供一个全局访问点来获取该实例。单例模式主要用于控制对某些共享资源的访问,例如配置管理器、连接池、线程池、日志对象等。
对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器
实现单例模式的关键点:
私有构造方法:确保外部代码不能通过构造器创建类的实例。
私有静态实例:持有类的唯一实例。
公有静态方法:提供全局访问点以获取实例,如果实例不存在,则在内部创建。
01、饿汉式
饿汉式单例(Eager Initialization)在类加载时就急切地创建实例,不管你后续用不用得到,这也是饿汉式的来源,简单但不支持延迟加载实例。
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
02、懒汉式
懒汉式单例(Lazy Initialization)在实际使用时才创建实例,这种实现方式需要考虑线程安全问题,因此一般会带上 synchronized 关键字
```java
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
工厂模式
工厂模式(Factory Pattern)主要用于创建对象,而不暴露创建对象的逻辑给客户端。
其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。
工厂模式的主要类型
①、简单工厂模式(Simple Factory):简单工厂模式包括一个工厂类,它提供一个方法用于创建对象。
②、工厂方法模式(Factory Method):定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类进行。
动物实体类:
猫实体类:
构建宠物的工厂:
猫工厂:
应用场景
工厂方法模式适用于数据库访问层,其中需要根据不同的数据库(如MySQL、PostgreSQL、Oracle)创建不同的数据库连接。工厂方法可以隐藏这些实例化逻辑,只提供一个统一的接口来获取数据库连接。
日志记录:当应用程序需要实现多种日志记录方式(如向文件记录、数据库记录或远程服务记录)时,可以使用工厂模式来设计一个灵活的日志系统,根据配置或环境动态决定具体使用哪种日志记录方式。
代理模式
主要目的是为了控制对对象的访问,通过在代理类中调用被代理类的方法实现功能增强
- 静态代理
动态代理
JDK动态代理:JDK原生的实现方式,只能代理实现接口的类,需要被代理的目标类必须实现接口,使用反射机制来代理接口方法。
cglib动态代理:通过继承被代理的目标类实现代理,所以不需要目标类实现接口。(CGLIB 通过动态生成一个需要被代理类的子类(即被代理类作为父类),该子类重写被代理类的所有不是 final 修饰的方法,并在子类中采用方法拦截的技术拦截父类所有的方法调用,进而织入横切逻辑。)
CGLib 实现步骤
创建一个实现接口 MethodInterceptor 的代理类,重写 intercept 方法;
创建获取被代理类的方法 getInstance(Object target);
获取代理类,通过代理调用方法。
JDK Proxy 和 CGLib 的区别主要体现在以下方面:
JDK Proxy : Java 语言自带的功能,无需通过加载第三方类实现;通过拦截器加反射的方式实现的;只能代理实现接口的类;实现和调用起来比较简单;
CGLib: 第三方提供的工具,基于 ASM 实现的,性能比较高;无需通过接口来实现,它是针对类实现代理,主要是对指定的类生成一个子类,它是通过实现子类的方式来完成调用的。
装饰模式
主要目的是为了给对象添加额外的功能。通过在装饰器类中调用被装饰对象的方法,并在其前后添加额外的功能实现功能增强。
策略和工厂模式来优化if else代码
策略模式
首先,利用策略模式来优化doSomething。
第一步、创建策略接口类。
第二步、根据不同的逻辑去实现策略。
工厂模式
其次,利用工厂模式集中创建实现所需要的策略对象。此处,是通过map来实现不同的策略对象的创建,与此同时,创建工厂类时,需要向外部提供一个可以供外部调用的方法,即:getMedalService()方法。
实际应用
通过工厂类中的getMedalService方法来实现了不同逻辑策略的调用,从而有效地提升了代码的整洁度,也方便了开发人员去根据不同的策略逻辑,去实现IMedalService接口