单例模式
预加载
1 2 3 4 5 6 7 8 9 10
| public class PreloadSingleton { private static PreloadSingleton instance = new PreloadSingleton();
//私有化构造函数 private PreloadSingleton(){};
public static PreloadSingleton getInstance(){ return instance; } }
|
缺点:可能会浪费内存,因为没有使用该对象时,就已经加载到内存。
懒加载
1 2 3 4 5 6 7 8 9 10 11 12
| public class LazySingleton { private static LazySingleton instance = null;
private LazySingleton(){};
public static LazySingleton getInstance(){ if(instance == null){ instance = new LazySingleton(); } return instance; } }
|
缺点:可能出现线程安全问题,if操作时可能多个线程同时进入。指令重排也可能让线程拿到未初始化的对象。
双检索单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class Singleton { private static volatile Singleton instance;
private Singleton() { }
public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
|
volatile
关键字:
volatile
关键字,确保多线程环境中对该变量的写操作能够立刻被其他线程可见,并防止 JVM 的指令重排序优化。在没有volatile
的情况下,可能会发生以下情况:
- 线程A部分初始化了
Singleton
对象,但尚未完全构造好对象的状态。
- 线程B看到非空的
instance
,但却获取到了未完全初始化的对象。
使用 volatile
关键字避免了这种情况。
双重检查锁定:
- 第一次检查:在进入同步块之前,检查
instance
是否为空。如果不为空,直接返回实例,避免每次都进入同步块,提升性能。
- 同步块:确保多个线程在第一次创建实例时不发生竞争。只有
instance
为 null
时,才进入同步块。
- 第二次检查:在同步块内部再次检查
instance
是否为空。原因是即使多个线程同时通过第一次检查,进入同步块的线程也只有一个能够执行到创建实例的代码。
代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介作用,客户端通过代理对象访问目标对象。代理模式可以用于延迟对象的创建、控制对对象的访问,或者添加额外的功能。
静态代理
静态代理由自己手动创建。代理类和目标类实现相同的接口,通过代理类来调用目标类的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| interface Service { void request(); }
class RealService implements Service { @Override public void request() { System.out.println("Executing request in RealService"); } }
class ServiceProxy implements Service { private RealService realService;
public ServiceProxy(RealService realService) { this.realService = realService; }
@Override public void request() { System.out.println("Proxy: Before request"); realService.request(); System.out.println("Proxy: After request"); } }
public class Client { public static void main(String[] args) { RealService realService = new RealService(); Service serviceProxy = new ServiceProxy(realService); serviceProxy.request(); } }
|
动态代理
动态代理是在运行时动态生成代理类,不需要手动编写代理类。Java提供了基于 java.lang.reflect.Proxy
的动态代理机制,代理类可以在运行时动态创建,并通过 InvocationHandler
来拦截方法调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| interface Service { void request(); }
class RealService implements Service { @Override public void request() { System.out.println("Executing request in RealService"); } }
class ServiceInvocationHandler implements InvocationHandler { private Object target;
public ServiceInvocationHandler(Object target) { this.target = target; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Proxy: Before request"); Object result = method.invoke(target, args); System.out.println("Proxy: After request"); return result; } }
public class Client { public static void main(String[] args) { RealService realService = new RealService(); Service serviceProxy = (Service) Proxy.newProxyInstance( realService.getClass().getClassLoader(), realService.getClass().getInterfaces(), new ServiceInvocationHandler(realService) ); serviceProxy.request(); } }
|
CGLIB代理
CGLIB 代理是通过继承的方式为目标对象创建代理,适用于没有实现接口的类。它通过生成目标类的子类来实现代理功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class RealService { public void request() { System.out.println("Executing request in RealService"); } }
class ServiceMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("CGLIB Proxy: Before request"); Object result = proxy.invokeSuper(obj, args); System.out.println("CGLIB Proxy: After request"); return result; } }
public class Client { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(RealService.class); enhancer.setCallback(new ServiceMethodInterceptor());
RealService serviceProxy = (RealService) enhancer.create(); serviceProxy.request(); } }
|
策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以相互替换。
假设有一个场景:我们想实现一个支付系统,用户可以选择不同的支付方式(如支付宝、微信支付和信用卡支付)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| interface PaymentStrategy { void pay(int amount); }
class AliPayStrategy implements PaymentStrategy { @Override public void pay(int amount) { System.out.println("Using Alipay to pay " + amount + " yuan."); } }
class WeChatPayStrategy implements PaymentStrategy { @Override public void pay(int amount) { System.out.println("Using WeChatPay to pay " + amount + " yuan."); } }
class CreditCardPayStrategy implements PaymentStrategy { @Override public void pay(int amount) { System.out.println("Using CreditCard to pay " + amount + " yuan."); } }
class PaymentContext { private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) { this.paymentStrategy = paymentStrategy; }
public void executePayment(int amount) { paymentStrategy.pay(amount); } }
public class Client { public static void main(String[] args) { PaymentContext context = new PaymentContext();
context.setPaymentStrategy(new AliPayStrategy()); context.executePayment(100);
context.setPaymentStrategy(new WeChatPayStrategy()); context.executePayment(200);
context.setPaymentStrategy(new CreditCardPayStrategy()); context.executePayment(300); } }
|
模版方法模式
在模板方法模式中,父类提供一个模板方法,定义了算法的骨架,具体的实现步骤由子类提供。它是一种代码复用的有效手段,适用于算法结构固定而部分实现不同的场景。
抽象类(AbstractClass):定义模板方法,确定算法的骨架,并且包含算法中的某些步骤的具体实现或抽象方法。
具体类(ConcreteClass):实现抽象类中定义的抽象方法,完成算法中的具体步骤。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| abstract class Beverage { public final void prepareBeverage() { boilWater(); brew(); pourInCup(); if (needsCondiments()) { addCondiments(); } }
public void boilWater() { System.out.println("Boiling water"); }
public void pourInCup() { System.out.println("Pouring into cup"); }
public abstract void brew();
public abstract void addCondiments();
public boolean needsCondiments() { return true; } }
class Tea extends Beverage { @Override public void brew() { System.out.println("Steeping the tea"); }
@Override public void addCondiments() { System.out.println("Adding lemon"); } }
class Coffee extends Beverage { @Override public void brew() { System.out.println("Dripping coffee through filter"); }
@Override public void addCondiments() { System.out.println("Adding sugar and milk"); }
@Override public boolean needsCondiments() { return false; } }
public class Client { public static void main(String[] args) { Beverage tea = new Tea(); tea.prepareBeverage();
Beverage coffee = new Coffee(); coffee.prepareBeverage(); } }
|