首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

【Java 設計模式】靜態代理模式深度解析:從原理到實戰

     編輯:Java 綜合教學

什麼是靜態代理?

在 23 種經典設計模式中,代理模式(Proxy Pattern)佔有一席之地。其核心定義是:為其他對象提供一種代理,以控制對這個對象的訪問。當某個對象不適合或無法直接引用另一個對象時,代理對象便能在客戶端與目標對象之間扮演中介角色。

代理模式的精髓在於:為了提供額外處理或不同操作,在實際對象與調用者之間插入一個代理對象。這些額外操作通常需要與實際對象通信。所謂「靜態」,是指在程序運行前,代理類與委托類的對應關係已經確定,亦即代理類的字節碼文件在編譯階段就已生成。

為何需要代理模式?

代理模式主要由三大角色構成:

  • 抽象角色:通過接口或抽象類聲明真實角色實現的業務方法。
  • 代理角色:實現抽象角色,持有真實角色引用,調用其業務邏輯並可附加自身操作(如日誌、權限控制)。
  • 真實角色:實現抽象角色,定義核心業務邏輯,供代理調用。

代理模式結構圖

採用代理模式開發,業務類只需專注核心邏輯,輔助功能(日誌、權限等)交由代理類處理,極大提升了業務類的復用性與內聚性。

靜態代理實戰演示

以用戶管理業務為例,需為新增用戶操作添加日誌記錄。方案一:直接在業務類中硬編碼日誌;方案二:使用靜態代理,將日誌邏輯置於代理類。下面通過代碼對比兩種方式。

1. 定義用戶管理接口

public interface UserManager {
    void addUser(String userId, String userName);
    void delUser(String userId);
    void modifyUser(String userId, String userName);
    String findUser(String userId);
}

2. 真實業務實現類(含硬編碼日誌版本)

public class UserManagerImpl implements UserManager {
    public void addUser(String userId, String userName) {
        // 方案一:直接在業務方法中添加日誌(註釋掉的代碼)
        // System.out.println("start-->>addUser() userId-->>" + userId);
        try {
            System.out.println("UserManagerImpl.addUser() userId-->>" + userId);
            // System.out.println("success-->>addUser()");
        } catch (Exception e) {
            e.printStackTrace();
            // System.out.println("error-->>addUser()");
            throw new RuntimeException();
        }
    }
    public void delUser(String userId) {
        System.out.println("UserManagerImpl.delUser() userId-->>" + userId);
    }
    public String findUser(String userId) {
        System.out.println("UserManagerImpl.findUser() userId-->>" + userId);
        return "查詢成功,找到用戶張三";
    }
    public void modifyUser(String userId, String userName) {
        System.out.println("UserManagerImpl.modifyUser() userId-->>" + userId);
    }
}

3. 靜態代理類(方案二:分離日誌邏輯)

public class UserManagerImplProxy implements UserManager {
    private UserManager userManager; // 持有真實對象引用

    public UserManagerImplProxy(UserManager userManager) {
        this.userManager = userManager;
    }

    public void addUser(String userId, String userName) {
        try {
            // 代理類增強:前置日誌
            System.out.println("開始添加用戶,調用方法:addUser() 用戶ID:userId-->>" + userId);
            userManager.addUser(userId, userName); // 調用真實業務
            // 代理類增強:後置日誌
            System.out.println("添加用戶成功!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("添加用戶失敗!請聯系管理員……");
        }
    }
    // 其他方法直接透傳
    public void delUser(String userId) { userManager.delUser(userId); }
    public String findUser(String userId) { return userManager.findUser(userId); }
    public void modifyUser(String userId, String userName) { userManager.modifyUser(userId, userName); }
}

4. 客戶端調用

public class Client {
    public static void main(String[] args) {
        // 使用代理類包裝真實對象
        UserManager userManager = new UserManagerImplProxy(new UserManagerImpl());
        userManager.addUser("0001", "張三");
        System.out.println(userManager.findUser("0001"));
    }
}

靜態代理的優缺點總結

優點:實現了業務邏輯與輔助邏輯的分離,降低耦合,提高復用性。

缺點:

  1. 代碼冗餘嚴重:代理類需實現接口所有方法,導致大量樣板代碼;接口新增方法時,所有實現類與代理類均需修改,維護成本高。
  2. 擴展性差:一個業務類對應一個代理類,業務類增多時代理類呈爆炸式增長,不適合大型項目。

如何解決這些痛點?動態代理應運而生,敬請期待下篇解析。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved