# 代理模式

## 目录
- [代理模式概念](#代理模式概念)
- [静态代理](#静态代理)
- [动态代理](#动态代理)
- [代理模式应用](#代理模式应用)
- [代理模式最佳实践](#代理模式最佳实践)
- [面试常见问题](#面试常见问题)

---

## 代理模式概念

### 定义

```java
// 代理模式：为其他对象提供一种代理以控制对这个对象的访问
// 代理对象在客户端和目标对象之间起到中介作用
```

### 使用场景

```java
// 1. 远程代理：为远程对象提供本地代表
// 2. 虚拟代理：延迟加载
// 3. 保护代理：控制访问权限
// 4. 智能代理：添加额外功能
```

---

## 静态代理

### 实现方式

```java
// 接口
public interface Subject {
    void request();
}

// 真实主题
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("Real Subject Request");
    }
}

// 代理类
public class Proxy implements Subject {
    private RealSubject realSubject;
    
    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        preRequest();
        realSubject.request();
        postRequest();
    }
    
    private void preRequest() {
        System.out.println("Pre Request");
    }
    
    private void postRequest() {
        System.out.println("Post Request");
    }
}

// 使用
Subject proxy = new Proxy();
proxy.request();
```

---

## 动态代理

### JDK 动态代理

```java
// JDK 动态代理
public class DynamicProxy implements InvocationHandler {
    private Object target;
    
    public DynamicProxy(Object target) {
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method: " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("After method: " + method.getName());
        return result;
    }
    
    public static Object createProxy(Object target) {
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new DynamicProxy(target)
        );
    }
}

// 使用
Subject realSubject = new RealSubject();
Subject proxy = (Subject) DynamicProxy.createProxy(realSubject);
proxy.request();
```

---

## 代理模式应用

### Android 中的应用

#### 1. Retrofit

```java
// Retrofit 使用动态代理
public interface ApiService {
    @GET("user/{id}")
    Call<User> getUser(@Path("id") int id);
}

// Retrofit 使用 Proxy 创建代理对象
ApiService api = retrofit.create(ApiService.class);
```

#### 2. Binder 代理

```java
// Binder 使用代理模式实现跨进程通信
// Service 端：真实对象
// Client 端：代理对象
```

---

## 代理模式最佳实践

### 1. 选择合适的代理类型

```java
// 简单场景：静态代理
// 复杂场景：动态代理
```

### 2. 避免过度使用

```java
// 不要为了使用而使用
// 只在需要时使用代理
```

---

## 面试常见问题

### Q1: 代理模式的原理？

**答案：**
- 为其他对象提供代理以控制访问
- 代理对象在客户端和目标对象之间起到中介作用

### Q2: 静态代理和动态代理的区别？

**答案：**
- **静态代理**：编译时确定，需要手动创建代理类
- **动态代理**：运行时确定，自动生成代理类

### Q3: Android 中的代理模式应用？

**答案：**
- Retrofit：使用动态代理创建 API 接口
- Binder：跨进程通信代理

---

*最后更新：2024年*
