算法策略的主动选择,拒绝if...else...(策略模式+简单工厂模式)

简介: 算法策略的主动选择,拒绝if...else...(策略模式+简单工厂模式)

算法策略的主动选择,拒绝if...else...(策略模式+简单工厂模式)


本文通过一个切换加解密算法的Demo来学习如何使代码的调用和封装都变的更加简单


1. 抽象策略接口

/**
 * 加密算法接口:封装算法的公共操作加密和解密
 * 
 * @author Spoon
 * @version 1.0.0
 */
public interface SecurityStrategy {
  /**
   * 加密
   */
  public String doEncryption(String key, String plaintext);
  /**
   * 解密
   */
  public String doDeciphering(String key, String ciphertext);
}


2. 策略算法的具体实现

/**
 * AES加密算法具体实现类
 * 
 * @author Spoon
 * @version 1.0.0
 */
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;
  }
}
/**
 * DES3加密算法具体实现类
 *
 * @author Spoon
 * @version 1.0.0
 */
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. 加密算法类型枚举

/**
 * 加密算法类型枚举
 * @author Spoon
 * @version 1.0.0
 */
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. 使用简单工厂获取具体实现

/**
 * 策略工厂类:将每个实现策略注册到工厂,并根据Type返回指定策略实现 
 * @author Spoon
 * @version 1.0.0
 */
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. 策略上下文完成工厂返回实现的具体调用

/**
 * 策略上下文:实际操作对象,接收传入的Type和必要参数,内部调用策略工厂类获取实际实现类进行加解密操作
 * 
 * @author Spoon
 * @version 1.0.0
 */
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

/**
 *  测试类
 *  String key_aes = "789tenc963qAzWsX";
 *  String key_des3 = "1234567890ASDFGH12345678";
 */
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("---------------结束测试-------------------")


相关文章
|
21天前
|
数据采集 存储 算法
Python 中的数据结构和算法优化策略
Python中的数据结构和算法如何进行优化?
|
18天前
|
算法
通过matlab分别对比PSO,反向学习PSO,多策略改进反向学习PSO三种优化算法
本项目使用MATLAB2022A版本,对比分析了PSO、反向学习PSO及多策略改进反向学习PSO三种优化算法的性能,主要通过优化收敛曲线进行直观展示。核心代码实现了标准PSO算法流程,加入反向学习机制及多种改进策略,以提升算法跳出局部最优的能力,增强全局搜索效率。
|
18天前
|
算法 搜索推荐
如何用CRDT算法颠覆文档协作模式?
在局域网环境下,高效文档协同编辑面临版本冲突等核心技术挑战,影响协作效率和成果质量。为解决此问题,可采用基于CRDT的算法,允许多用户无冲突实时编辑;或将协同操作模块化,通过任务看板优化协作流程,减少冲突,提高团队效率。未来,局域网协同编辑将更加场景化与个性化,深入探索组织协作文化。
|
20天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
49 1
|
29天前
|
算法
优化策略:揭秘钢条切割与饼干分发的算法艺术
本文探讨了钢条切割与饼干分发两个经典算法问题,展示了算法在解决实际问题中的应用。钢条切割问题通过动态规划方法,计算出不同长度钢条的最大盈利切割方式,考虑焊接成本后问题更为复杂。饼干分发问题则采用贪心算法,旨在尽可能多的喂饱孩子,分别讨论了每个孩子一块饼干和最多两块饼干的情况。这些问题不仅体现了数学的精妙,也展示了工程师的智慧与创造力。
37 4
|
2月前
|
数据采集 缓存 算法
算法优化的常见策略有哪些
【10月更文挑战第20天】算法优化的常见策略有哪些
|
2月前
|
前端开发 算法 JavaScript
无界SaaS模式深度解析:算力算法、链接力、数据确权制度
私域电商的无界SaaS模式涉及后端开发、前端开发、数据库设计、API接口、区块链技术、支付和身份验证系统等多个技术领域。本文通过简化框架和示例代码,指导如何将核心功能转化为技术实现,涵盖用户管理、企业店铺管理、数据流量管理等关键环节。
|
4月前
|
缓存 算法 前端开发
深入理解缓存淘汰策略:LRU和LFU算法的解析与应用
【8月更文挑战第25天】在计算机科学领域,高效管理资源对于提升系统性能至关重要。内存缓存作为一种加速数据读取的有效方法,其管理策略直接影响整体性能。本文重点介绍两种常用的缓存淘汰算法:LRU(最近最少使用)和LFU(最不经常使用)。LRU算法依据数据最近是否被访问来进行淘汰决策;而LFU算法则根据数据的访问频率做出判断。这两种算法各有特点,适用于不同的应用场景。通过深入分析这两种算法的原理、实现方式及适用场景,本文旨在帮助开发者更好地理解缓存管理机制,从而在实际应用中作出更合理的选择,有效提升系统性能和用户体验。
221 1
|
4月前
|
算法 语音技术
支付宝商业化广告算法问题之在ODL模型优化过程中,采取什么策略来提高模型的泛化能力呢
支付宝商业化广告算法问题之在ODL模型优化过程中,采取什么策略来提高模型的泛化能力呢
|
5月前
|
机器学习/深度学习 数据采集 算法
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机回归模型(SVR算法)项目实战
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机回归模型(SVR算法)项目实战
下一篇
DataWorks