设计模式
说说什么是单例模式
单例模式是一种常用的软件设计模式,在应用这个模式时,单例对象的类必须保证只有一个实例存在,整个系统只能使用一个对象实例。 这种模式在需要控制资源访问或共享资源的场景中尤为重要。 优点:不会频繁地创建和销毁对象,浪费系统资源。
核心实现方式
单例模式有多种实现方式,每种方式都有其适用场景和优缺点:
- 饿汉式单例:类加载时就创建实例,线程安全但可能造成资源浪费
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
- 懒汉式单例(双重检查锁):延迟加载,原本是线程不安全的,但使用双重检查锁可以保证线程安全
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- 静态内部类实现:结合了饿汉式的线程安全和懒汉式的延迟加载优势
public class Singleton {
private Singleton() {}
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
- 枚举式单例:Effective Java推荐的方式,防止反射攻击,线程安全
public enum Singleton {
INSTANCE;
public void doSomething() {
// 方法实现
}
}
说说工厂模式
简单工厂模式又叫静态工厂方法模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。比如,一台咖啡机就可以理解为一个工厂模式,你只需要按下想喝的咖啡品类的按钮 (摩卡或拿铁),它就会给你生产一杯相应的咖啡,你不需要管它内部的具体实现,只要告诉它你的需求即可。
- 优点: 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供 了专门的工厂类用于创建对象; 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量; 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
- 缺点: 不易拓展,一旦添加新的产品类型,就不得不修改工厂的创建逻辑; 产品类型较多时,工厂的创建逻辑可能过于复杂,一旦出错可能造成所有产品的创建失败,不利于系统的维护。
说说你对代理模式的理解
代理模式是给某一个对象提供一个代理,并由代理对象控制对原对象的引用。
- 优点:代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度; 可以灵活地隐藏被代理对象的部分功能和服务,也增加额外的功能和服务。
- 缺点:由于使用了代理模式,因此程序的性能没有直接调用性能高; 使用代理模式提高了代码的复杂度。
类似黄牛卖火车票、婚姻介绍所
注意了,问代理模式的时候,很有可能会问:动态代理。在Spring篇中已经讲述过,如果你把动态代理讲了后,很有可能还会问什么是静态代理?一个动一个是静,大致也能猜出来,就是中间代理层是我们手动写的,通常说的代理模式就是静态代理。
- 静态代理:在程序运行前就已经存在代理类的字节码文件
- 动态代理:在程序运行时生成代理类,主要有JDK动态代理和CGLIB动态代理
模板方法模式
模板方法模式是指定义一个算法骨架,将具体内容延迟到子类去实现。
优点: 提高代码复用性:将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中; 实现了反向控制:通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制并且符合开闭原则。
类似于抽象类和接口,抽象类是对一类事物的抽象,而接口是对一类行为的抽象。模板方法模式是对算法的抽象,而抽象类和接口是对实现的抽象。