C#设计模式之Strategy策略模式解决007大破密码危机问题示例

C#设计模式之Strategy策略模式解决007大破密码危机问题示例

策略模式介绍

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。

策略模式的实现方法

在策略模式中,定义一个具体的策略接口(抽象类),接口中定义公共的方法(通用的算法),具体的策略类实现这个接口,实现各自的算法。在程序中定义一个Context类,该类中有一个私有成员变量strategy,它是一个父级策略类,Context类中有一个用来设置策略的方法setStrategy和一个用来执行策略的方法executeStrategy。通过调用setStragety方法可以动态地选择不同的策略。

策略模式的使用场景

策略模式主要用于解决许多算法彼此之间只有细微的不同的问题。就像一个类拥有无数的方法一样,但是许多方法只是细微的不同点,这时候就可以用策略模式将这些不同点定义为一个接口,然后在每个具体实现中实现自己的算法。这样将代码封装之后,代码就易于维护和扩展。通常用策略模式来解决算法的切换问题。

Strategy策略模式解决007大破密码危机问题示例

假设在007电影中,恶势力组织需要对MI6总部的密码进行攻击,他们知道密码是用凯撒密码加密的,只有一个生成密钥的秘密方法。Bond无法破解秘密方法,所以他需要写一个破解程序,采用Strategy策略模式解决问题。

我们先定义一个接口ICodeStrategy,然后定义一个抽象类CodeStrategy,它实现了ICodeStrategy接口中的所有方法,并且提供了一个密钥生成函数GenerateKey(),其他具体的策略类都是从CodeStrategy基类中派生出来的。

public interface ICodeStrategy
{
    string Encrypt(string plain, string key);
    string Decrypt(string cipher, string key);
}

public abstract class CodeStrategy : ICodeStrategy
{
    public string Encrypt(string plain, string key)
    {
        return DoEncrypt(plain, key);
    }

    public string Decrypt(string cipher, string key)
    {
        return DoDecrypt(cipher, key);
    }

    protected abstract string DoEncrypt(string plain, string key);
    protected abstract string DoDecrypt(string cipher, string key);

    public virtual string GenerateKey()
    {
        return Guid.NewGuid().ToString().Substring(0, 8);
    }
}

下面是凯撒密码的加密解密算法实现,即从CodeStrategy基类中派生出来的策略类CaesarCodeStrategyReverseCodeStrategy

public class CaesarCodeStrategy : CodeStrategy
{
    protected override string DoEncrypt(string plain, string key)
    {
        int shift = int.Parse(key);
        StringBuilder result = new StringBuilder();
        foreach (char c in plain)
        {
            if (char.IsLetter(c))
            {
                if (char.IsUpper(c))
                    result.Append((char)('A' + (c - 'A' + shift) % 26));
                else
                    result.Append((char)('a' + (c - 'a' + shift) % 26));
            }
            else
            {
                result.Append(c);
            }
        }
        return result.ToString();
    }

    protected override string DoDecrypt(string cipher, string key)
    {
        int shift = int.Parse(key);
        StringBuilder result = new StringBuilder();
        foreach (char c in cipher)
        {
            if (char.IsLetter(c))
            {
                if (char.IsUpper(c))
                    result.Append((char)('A' + (c - 'A' - shift + 26) % 26));
                else
                    result.Append((char)('a' + (c - 'a' - shift + 26) % 26));
            }
            else
            {
                result.Append(c);
            }
        }
        return result.ToString();
    }
}

public class ReverseCodeStrategy : CodeStrategy
{
    protected override string DoEncrypt(string plain, string key)
    {
        char[] charArray = plain.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }

    protected override string DoDecrypt(string cipher, string key)
    {
        char[] charArray = cipher.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }
}

最后,我们定义一个Context类CodeContext

public class CodeContext
{
    private readonly ICodeStrategy _strategy;

    public CodeContext(ICodeStrategy strategy)
    {
        _strategy = strategy;
    }

    public void SetStrategy(ICodeStrategy strategy)
    {
        _strategy = strategy;
    }

    public string GenerateKey()
    {
        return _strategy.GenerateKey();
    }

    public string ExecStrategy(string plain, string key)
    {
        return _strategy.Encrypt(plain, key);
    }

    public string UnexecStrategy(string cipher, string key)
    {
        return _strategy.Decrypt(cipher, key);
    }
}

现在,我们可以创建一个CodeContext对象,设置一个策略类,然后执行该策略类的密钥生成和加密过程:

CodeContext context = new CodeContext(new CaesarCodeStrategy());

string plain = "mi6headquarters";
string key = context.GenerateKey();
string cipher = context.ExecStrategy(plain, key);

Console.WriteLine("plain: {0}", plain);
Console.WriteLine("key: {0}", key);
Console.WriteLine("cipher: {0}", cipher);

执行结果如下:

plain: mi6headquarters
key: 3c76ada6
cipher: pl9ealikxkmexiyoi

接下来,我们可以用同样的过程执行秘钥解密过程。

string plain2 = context.UnexecStrategy(cipher, key);

Console.WriteLine("cipher2: {0}", cipher);
Console.WriteLine("key2: {0}", key);
Console.WriteLine("plain2: {0}", plain2);

执行结果如下:

cipher2: pl9ealikxkmexiyoi
key2: 3c76ada6
plain2: mi6headquarters

由此看来,通过Strategy策略模式,我们可以方便地实现算法类的扩展和修改。而且,通过上述方法是不需要进行大量的代码修改和重构的。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#设计模式之Strategy策略模式解决007大破密码危机问题示例 - Python技术站

(0)
上一篇 2023年6月1日
下一篇 2023年6月1日

相关文章

  • 如何运行编译.NetCore的源码?

    作为.net的开发人员,为了能更好的code,我们要知其然并知其所以然,了解.netcore的源码是我们的基本素养✊ 源码地址 .NET Platform (github.com) 这个是.net在github上开源的源码地址aspnetcore 这个是.netcore的源码地址 构建方法 构建有几点需要注意一下: 构建比较费时间,可以摸个?; 同时构建还需…

    C# 2023年4月18日
    00
  • C#备忘录模式(Memento Pattern)实例教程

    C#备忘录模式(Memento Pattern)实例教程 备忘录模式(Memento Pattern)是一种行为型设计模式,它允许将一个对象的内部状态保存到一个外部的备忘录对象中,从而可以在需要时将对象恢复到先前的状态。在本篇教程中,我们将介绍C#中备忘录模式的使用方法和实现步骤,并提供两个示例说明。 示例一:备忘录模式的基本使用 步骤一:创建备忘录类 首先…

    C# 2023年6月8日
    00
  • C#方法的总结详解

    C#方法的总结详解 什么是C#方法 C#方法(Method)是一段预定义代码,用于执行特定功能。当我们需要执行特定操作时,调用已经定义好的方法能够让代码更加简洁明了。 C#方法的语法规则 C#方法的基本语法规则如下: [访问修饰符] [static] 返回类型 方法名 ([参数列表]) { // 方法体 return 返回值; } 访问修饰符:指定方法在何处…

    C# 2023年5月15日
    00
  • C#泛型详解及关键字作用

    C#泛型详解及关键字作用 泛型的介绍 C#泛型是一个高度灵活且强大的特性,能够让我们编写具有通用性的代码。在不加使用泛型的情况下,我们需要对不同类型的数据写出不同的代码。而使用了泛型之后,我们可以编写出更加通用的代码,同时减少了代码的重复,增强了代码的可重用性。 泛型类别通常用于集合类库,因为集合类库只处理与它们分别正在处理的元素类型无关的逻辑。 泛型的语法…

    C# 2023年6月1日
    00
  • C#统计字符串里中文汉字个数的方法

    下面我将详细讲解“C#统计字符串里中文汉字个数的方法”的完整攻略。 1. 确定需求和情景 在开发过程中,我们需要先确定需求和情景。经过分析,我们的需求是:编写一段 C# 代码,统计给定字符串里汉字的个数。情景是:我们需要在一个网站中统计每个评论中汉字的个数,以便进行敏感信息监控。 2. 了解中文汉字的编码 在编写代码前,需要了解中文汉字的编码情况。中文汉字采…

    C# 2023年6月8日
    00
  • C# 实现简易的串口监视上位机功能附源码下载

    下面是详细的讲解: 一、准备工作 在使用C#实现简易的串口监视上位机功能前,需要做一些准备工作:- 确定需要监视的串口号和波特率- 判断串口是否已打开,打开串口并设置参数- 创建事件处理函数,用于接收和解析串口数据 二、实现步骤 第一步、创建一个新的C#项目 打开Visual Studio,创建一个新的Windows Forms应用程序。 第二步、添加控件 …

    C# 2023年5月15日
    00
  • C#用websocket实现简易聊天功能(客户端)

    下面是C#用websocket实现简易聊天功能(客户端)的完整攻略。 1. 准备工作 在开始实现聊天功能之前,你需要先准备好以下几件事情: 安装websocket库:你可以通过在Visual Studio中打开NuGet包管理器,然后搜索websocket来安装websocket库。 了解websocket连接的基本知识:websocket是一种基于TCP协…

    C# 2023年5月15日
    00
  • winform获取当前名称实例汇总

    要实现WinForm获取当前名称实例的功能,我们可以使用以下步骤: 1.使用System.Diagnostics.Process类获取当前正在运行的所有进程。 using System.Diagnostics; Process[] processes = Process.GetProcesses(); 2.使用LINQ查询找到我们需要的进程实例。 Proce…

    C# 2023年6月7日
    00
合作推广
合作推广
分享本页
返回顶部