java进阶(三):单例、工厂、模版方法与代理模式详解
单例模式:确保唯一实例
单例模式的核心目标是确保一个类在整个应用程序中只有一个实例,并提供一个全局访问点。
实现方式
饿汉式单例:
public class Runtime {private static Runtime currentRuntime = new Runtime();public static Runtime getRuntime() {return currentRuntime;}private Runtime() {}
}
优点:线程安全,实现简单
缺点:类加载时就创建实例,可能延长启动时间
懒汉式单例(双重检查锁定):
public class Window {private volatile static Window window = null;private Window() {}public static Window getWindow() {if(window == null) {synchronized (Window.class) {if(window == null) {window = new Window();}}}return window;}
}
volatile
关键字防止指令重排序双重检查减少同步开销
优点:延迟加载,节省资源
缺点:实现稍复杂
工厂模式:对象创建的艺术
工厂模式解决对象创建的问题,分为简单工厂、工厂方法和抽象工厂三种形式。
1. 简单工厂
public class CanFactory {public static Can createCan(String name) {if(name.equals("aodi")) return new Aodi();if(name.equals("bmw")) return new Bmw();if(name.equals("dazhong")) return new Dazhong();return null;}
}
优点:集中管理对象创建
缺点:违反开闭原则,新增产品需要修改工厂代码
2. 工厂方法
public abstract class Factory {public abstract Product createProduct();
}
为每个产品提供一个专门工厂
优点:符合开闭原则,扩展性好
缺点:类数量增多
3. 抽象工厂
public interface AbstractFactory {Button createButton();Checkbox createCheckbox();
}
一个工厂可以创建同一产品族的不同产品
适合产品族扩展场景
例如:汽车工厂生产轿车、SUV等多类型车辆
模版方法模式:定义算法骨架
abstract class Template {// 模版方法定义流程public final void templateMethod() {step1();step2();step3();}// 固定实现private void step1() { /*...*/ }// 需要子类实现protected abstract void step2();// 可选实现protected void step3() { /*默认实现*/ }
}
优点:代码复用,反向控制
缺点:增加系统复杂度
代理模式:控制对象访问
1. 静态代理
interface Subject {void request();
}class RealSubject implements Subject {public void request() { /*业务逻辑*/ }
}class Proxy implements Subject {private RealSubject realSubject;public void request() {preRequest();realSubject.request();postRequest();}
}
优点:不修改目标对象即可扩展功能
缺点:一个代理类只能代理一种类型
2. 动态代理
JDK动态代理:
// JDK 动态代理
Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),(proxy, method, args) -> {// 前置处理Object result = method.invoke(target, args);// 后置处理return result;});
要求目标类必须实现接口
CGLIB代理:
通过生成子类实现代理
不要求目标类实现接口
Spring AOP默认使用方式
总结
设计模式是解决特定问题的优秀实践:
单例模式确保全局唯一实例
工厂模式封装对象创建过程
模版方法模式固定算法流程
代理模式控制对象访问
合理运用这些模式可以使代码更灵活、更易维护,但也要避免过度设计。根据实际场景选择最适合的模式才是关键。