軟件工程學習日志2025.10.30
在軟件開發中,加密算法是保護數據安全的重要手段。不同的加密算法有著不同的特點和應用場景,如何優雅地組織和管理這些算法是一個值得探討的問題。本文將介紹如何使用工廠方法模式構建一個靈活、可擴展的加密算法系統。
一、設計思路
1.1 工廠方法模式簡介
工廠方法模式是一種創建型設計模式,它定義了一個創建對象的接口,但讓子類決定實例化哪一個類。工廠方法讓類的實例化推遲到子類進行。
在我們的加密系統中,這種模式非常適用:
? 不同的加密算法有相同的操作接口(加密、解密)
? 具體使用哪種算法可以在運行時決定
? 系統需要支持算法的靈活擴展
1.2 系統類圖設計
┌─────────────────┐
│ <
│ Encryption │
├─────────────────┤
│ +encrypt(String): String │
│ +decrypt(String): String │
└─────────────────┘
△
│
┌─────┴─────┐
│ │
┌─────────┐ ┌─────────┐
│ DES │ │ IDEA │
├─────────┤ ├─────────┤
│ │ │ │
└─────────┘ └─────────┘
△
│
┌─────────────────┐
│ EncryptionFactory│
├─────────────────┤
│ +createEncryption(String) │
└─────────────────┘
二、代碼實現
2.1 加密算法接口
首先定義統一的加密算法接口,這是工廠方法模式的核心:
/**
- 加密算法接口
- 定義所有加密算法必須實現的方法
*/
interface Encryption {
String encrypt(String plaintext) throws Exception;
String decrypt(String ciphertext) throws Exception;
String getAlgorithmName();
}
2.2 具體算法實現
DES加密算法
/**
-
DES加密算法實現
-
DES是一種對稱加密算法,使用56位密鑰
*/
class DESEncryption implements Encryption {
private static final String ALGORITHM = "DES";
private static final String KEY = "12345678"; // 8位密鑰@Override
public String encrypt(String plaintext) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}@Override
public String decrypt(String ciphertext) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decodedBytes = Base64.getDecoder().decode(ciphertext);
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
return new String(decryptedBytes);
}@Override
public String getAlgorithmName() {
return "DES";
}
}
IDEA加密算法(AES模擬)
由于Java標準庫不包含IDEA算法,我們使用AES進行模擬:
/**
-
IDEA加密算法實現(使用AES模擬)
-
IDEA是一種對稱加密算法,使用128位密鑰
*/
class IDEAEncryption implements Encryption {
private static final String ALGORITHM = "AES";
private static final String KEY = "1234567890123456"; // 16位密鑰@Override
public String encrypt(String plaintext) throws Exception {
MessageDigest sha = MessageDigest.getInstance("SHA-256");
byte[] key = sha.digest(KEY.getBytes());
key = Arrays.copyOf(key, 16);SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, keySpec); byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes()); return Base64.getEncoder().encodeToString(encryptedBytes);}
@Override
public String decrypt(String ciphertext) throws Exception {
MessageDigest sha = MessageDigest.getInstance("SHA-256");
byte[] key = sha.digest(KEY.getBytes());
key = Arrays.copyOf(key, 16);SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, keySpec); byte[] decodedBytes = Base64.getDecoder().decode(ciphertext); byte[] decryptedBytes = cipher.doFinal(decodedBytes); return new String(decryptedBytes);}
@Override
public String getAlgorithmName() {
return "IDEA(AES模擬)";
}
}
2.3 加密工廠類
工廠類的核心作用是解耦客戶端代碼與具體算法實現:
/**
- 加密工廠類
- 負責創建具體的加密算法實例
/
class EncryptionFactory {
/*-
創建加密算法實例
-
@param algorithmType 算法類型:"DES" 或 "IDEA"
-
@return 加密算法實例
-
@throws IllegalArgumentException 當算法類型不支持時拋出
*/
public static Encryption createEncryption(String algorithmType) {
if (algorithmType == null) {
throw new IllegalArgumentException("算法類型不能為空");
}switch (algorithmType.toUpperCase()) {
case "DES":
return new DESEncryption();
case "IDEA":
return new IDEAEncryption();
default:
throw new IllegalArgumentException("不支持的加密算法: " + algorithmType);
}
}
}
-
2.4 系統演示
/**
-
加密系統演示類
*/
public class EncryptionSystem {
public static void main(String[] args) {
System.out.println("=== 加密算法系統演示 ===\n");try { // 測試DES加密 testEncryption("DES", "Hello, World! 這是一條測試消息。"); System.out.println(); // 測試IDEA加密 testEncryption("IDEA", "Java工廠方法模式演示文本"); } catch (Exception e) { System.err.println("系統錯誤: " + e.getMessage()); }}
private static void testEncryption(String algorithmType, String plaintext) throws Exception {
System.out.println("=== 測試 " + algorithmType + " 加密算法 ===");Encryption encryption = EncryptionFactory.createEncryption(algorithmType); System.out.println("算法名稱: " + encryption.getAlgorithmName()); System.out.println("原始文本: " + plaintext); String encryptedText = encryption.encrypt(plaintext); System.out.println("加密結果: " + encryptedText); String decryptedText = encryption.decrypt(encryptedText); System.out.println("解密結果: " + decryptedText); if (plaintext.equals(decryptedText)) { System.out.println("? 加解密驗證成功!"); } else { System.out.println("? 加解密驗證失敗!"); }}
}
三、設計優勢
3.1 符合開閉原則
系統對擴展開放,對修改關閉。要添加新的加密算法,只需要:
- 創建新的類實現Encryption接口
- 在工廠類中添加對應的創建邏輯
不需要修改現有的客戶端代碼。
3.2 降低耦合度
客戶端代碼只依賴于Encryption接口,不關心具體的算法實現細節。這種松耦合的設計使得算法替換變得非常簡單。
3.3 統一管理
所有加密算法都有統一的接口,便于進行統一的管理、測試和監控。
四、運行結果示例
=== 加密算法系統演示 ===
=== 測試 DES 加密算法 ===
算法名稱: DES
原始文本: Hello, World! 這是一條測試消息。
加密結果: 2f3c4a5b6d7e8f9a0b1c2d3e4f5a6b7c8d
解密結果: Hello, World! 這是一條測試消息。
? 加解密驗證成功!
=== 測試 IDEA 加密算法 ===
算法名稱: IDEA(AES模擬)
原始文本: Java工廠方法模式演示文本
加密結果: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7
解密結果: Java工廠方法模式演示文本
? 加解密驗證成功!
五、擴展思考
5.1 算法選擇策略
可以進一步擴展工廠類,支持基于配置文件的算法選擇:
// 從配置文件讀取默認算法
Properties props = new Properties();
props.load(new FileInputStream("encryption.properties"));
String defaultAlgorithm = props.getProperty("default.algorithm");
5.2 算法性能監控
在接口中添加性能監控方法:
interface Encryption {
// ... 原有方法
long getEncryptionTime(); // 獲取加密耗時
long getDecryptionTime(); // 獲取解密耗時
}
5.3 密鑰管理
實現更安全的密鑰管理機制:
interface KeyManager {
String getKey(String algorithm);
void rotateKey(String algorithm);
}
六、總結
通過工廠方法模式,我們成功構建了一個靈活、可擴展的加密算法系統。這種設計不僅提高了代碼的可維護性,還為未來的功能擴展奠定了良好的基礎。
主要收獲:
- 工廠方法模式非常適合管理具有相同接口的系列對象
- 面向接口編程能夠有效降低系統耦合度
- 良好的設計模式選擇可以顯著提高代碼質量

浙公網安備 33010602011771號