算法策略的主动选择,拒绝if...else...(策略模式+简单工厂模式)
本文通过一个切换加解密算法的Demo来学习如何使代码的调用和封装都变的更加简单
1. 抽象策略接口
| |
| |
| |
| |
| |
| |
| public interface SecurityStrategy { |
| |
| |
| |
| public String doEncryption(String key, String plaintext); |
| |
| |
| |
| |
| public String doDeciphering(String key, String ciphertext); |
| } |
| |
2. 策略算法的具体实现
| |
| |
| |
| |
| |
| |
| public class AesStrategy implements SecurityStrategy{ |
| |
| @Override |
| public String doEncryption(String key, String plaintext) { |
| String dec = ""; |
| try { |
| dec = AESUtil.encrypt(plaintext, key, "UTF-8"); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return dec; |
| } |
| |
| @Override |
| public String doDeciphering(String key, String ciphertext) { |
| String enc = ""; |
| try { |
| enc = AESUtil.decrypt(ciphertext, key); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return enc; |
| } |
| |
| } |
| |
| |
| |
| |
| |
| |
| public class Des3Strategy implements SecurityStrategy{ |
| |
| @Override |
| public String doEncryption(String key, String plaintext) { |
| String dec = ""; |
| try { |
| dec = ThreeDES.encode(plaintext, key); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return dec; |
| } |
| |
| @Override |
| public String doDeciphering(String key, String ciphertext) { |
| String enc = ""; |
| try { |
| enc = ThreeDES.decode(ciphertext, key); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return enc; |
| } |
| |
| } |
| |
3. 加密算法类型枚举
| |
| |
| |
| |
| |
| public enum StrategyType { |
| AES(1,"AES加密算法"), |
| DES3(2,"DES3加密算法"); |
| |
| private int index; |
| private String desc; |
| |
| private StrategyType(int index, String desc){ |
| this.index = index; |
| this.desc = desc; |
| } |
| |
| public int index() { |
| return index; |
| } |
| |
| public String desc() { |
| return desc; |
| } |
| } |
| |
4. 使用简单工厂获取具体实现
| |
| |
| |
| |
| |
| |
| public class StrategyFactory { |
| private static Map<Integer, SecurityStrategy> services = new ConcurrentHashMap<Integer, SecurityStrategy>(); |
| |
| static { |
| services.put(StrategyType.AES.index(), new AesStrategy()); |
| services.put(StrategyType.DES3.index(), new Des3Strategy()); |
| } |
| |
| private StrategyFactory() { |
| } |
| |
| public static SecurityStrategy getSecurity(Integer type) { |
| return services.get(type); |
| } |
| } |
5. 策略上下文完成工厂返回实现的具体调用
| |
| |
| |
| |
| |
| |
| public class StrategyContext { |
| private SecurityStrategy strategy; |
| |
| public StrategyContext() { |
| } |
| |
| public SecurityStrategy getStrategy() { |
| return strategy; |
| } |
| |
| public void setStrategy(SecurityStrategy strategy) { |
| this.strategy = strategy; |
| } |
| |
| public String executeEncryptionStrategy(Integer type, String key, String plaintext) { |
| strategy = StrategyFactory.getSecurity(type); |
| return strategy.doEncryption(key, plaintext); |
| } |
| |
| public String executeDecipheringStrategy(Integer type, String key, String ciphertext) { |
| strategy = StrategyFactory.getSecurity(type); |
| return strategy.doDeciphering(key, ciphertext); |
| } |
| } |
6. Test
| |
| |
| |
| |
| |
| public class Main { |
| @SuppressWarnings("resource") |
| public static void main(String[] args) { |
| |
| String plaintext = "ABCDEFGHIJKLMNOPQRST"; |
| |
| System.out.println("请选择加密算法(AES:1, DES3:2) :"); |
| int type = new Scanner(System.in).nextInt(); |
| |
| System.out.println("请输入加密秘钥 :"); |
| String key = new Scanner(System.in).nextLine(); |
| |
| StrategyContext context = new StrategyContext(); |
| System.out.println(context.executeEncryptionStrategy(type, key, plaintext)); |
| } |
| } |
通过测试Main方法可以看出,在增加加密算法后对调用方来说只需要关注加密算法的Type值就可以,调用形式也没有发生改变,没有使用条件语句进行判断,减少了调用时出错的风险,对于提供方来说,主要关注点就是策略算法的具体实现,并添加相应的枚举后将实现的策略注册到策略工厂中即可。
Python版本 :
| from abc import ABCMeta,abstractmethod |
| |
| |
| class SecurityStrategy: |
| __metaclass__ = ABCMeta |
| |
| @abstractmethod |
| def doEncryption(self, key, plaintext): |
| pass |
| |
| @abstractmethod |
| def doDeciphering(self, key, ciphertext): |
| pass |
| from SecurityStrategy import SecurityStrategy |
| |
| |
| class AesStrategy(SecurityStrategy): |
| def doEncryption(self, key, plaintext): |
| print('AES === > ', 'key : ', key, 'plaintext : ', plaintext) |
| |
| def doDeciphering(self, key, ciphertext): |
| print('AES === > ', 'key : ', key, 'ciphertext : ', ciphertext) |
| from SecurityStrategy import SecurityStrategy |
| |
| |
| class Des3Strategy(SecurityStrategy): |
| def doEncryption(self, key, plaintext): |
| print('Des3 === > ', 'key : ', key, 'plaintext : ', plaintext) |
| |
| def doDeciphering(self, key, ciphertext): |
| print('Des3 === > ', 'key : ', key, 'ciphertext : ', ciphertext) |
| |
| from enum import Enum |
| |
| |
| class StrategyType(Enum): |
| AES = 1 |
| DES3 = 2 |
| from StrategyType import StrategyType |
| from impl.AesStrategy import AesStrategy |
| from impl.Des3Strategy import Des3Strategy |
| |
| |
| class StrategyFactory: |
| services = { |
| StrategyType.AES.value: AesStrategy(), |
| StrategyType.DES3.value: Des3Strategy() |
| } |
| |
| @staticmethod |
| def getSecurity(type): |
| return StrategyFactory.services[type] |
| from StrategyFactory import StrategyFactory |
| |
| |
| class StrategyContext: |
| |
| @staticmethod |
| def executeEncryptionStrategy(type, key, plaintext): |
| return StrategyFactory.getSecurity(type).doEncryption(key, plaintext) |
| |
| @staticmethod |
| def executeDecipheringStrategy(type, key, ciphertext): |
| return StrategyFactory.getSecurity(type).doDeciphering(key, ciphertext) |
| from StrategyContext import StrategyContext |
| |
| if __name__ == '__main__': |
| print("---------------开始测试-------------------") |
| StrategyContext.executeEncryptionStrategy(1, '1234567890ASDFGH12345678', 'ABCDEFGHIJKLMNOPQRST') |
| StrategyContext.executeDecipheringStrategy(1, '1234567890ASDFGH12345678', 'ABCDEFGHIJKLMNOPQRST') |
| StrategyContext.executeEncryptionStrategy(2, '1234567890ASDFGH12345678', 'ABCDEFGHIJKLMNOPQRST') |
| StrategyContext.executeDecipheringStrategy(2, '1234567890ASDFGH12345678', 'ABCDEFGHIJKLMNOPQRST') |
| print("---------------结束测试-------------------") |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)