设计模式

refactoringgurusourcemaking

创建型模式

单例模式

  • 提前创建单例:适用于频繁使用,或者单例占用资源较少的情况。最简单创建单例的方式是使用枚举类。
  • 延迟创建单例:存在多线程问题,可以直接使用 synchronized 对整个方法进行同步。但实际上只有在第一次调用时才需要同步,所以更优的实现是使用双重检查加锁以及 volatile 关键字。
  • 当使用多个类加载器、反射和序列化/反序列化时,要注意避免创建多个单例实例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public final class Singleton {

private volatile static Singleton instance;
public String value;

private Singleton(String value) {
this.value = value;
}

public static Singleton getInstance(String value) {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton(value);
}
}
}
return instance;
}
}

结构型模式

代理模式

Java 在 java.lang.reflect 包中有自己的代理支持,利用该包可以动态地创建代理类,所以该技术被称为动态代理

  • 实现 InvocationHandler 接口。
  • 以指定的对象和 InvocationHandler 实现类为参数,调用 Proxy.newProxyInstance 方法,创建代理对象。
  • 将代理对象强制类型转换为指定的对象所实现的某个接口类型,然后调用方法。
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
interface Person {

void foo();
}

class PersonImpl implements Person {

@Override
public void foo() {
System.out.println(this.getClass().getName());
}
}

class MyInvocationHandler implements InvocationHandler {

private Person person;

public MyInvocationHandler(Person person) {
this.person = person;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 逻辑处理
System.out.println(this.getClass().getName());
return method.invoke(person, args);
}
}

class ProxyFactory {

public static Person getProxyInstance(Person person) {
return (Person) Proxy.newProxyInstance(
person.getClass().getClassLoader(),
person.getClass().getInterfaces(),
new MyInvocationHandler(person));
}
}

public class DynamicProxy {

public static Person getProxyInstance(Person person) {
return (Person) Proxy.newProxyInstance(
person.getClass().getClassLoader(),
person.getClass().getInterfaces(),
new MyInvocationHandler(person));
}

public static void main(String[] args) {
Person person = new PersonImpl();
Person proxyInstance = getProxyInstance(person);
proxyInstance.foo();
}
}
作者

Ligh0x74

发布于

2024-08-16

更新于

2024-08-16

许可协议

评论