设计模式之策略模式(Strategy)

本文介绍了策略模式的基本概念,通过实例展示了其在个人所得税收费方式上的应用,并探讨了策略模式与简单工厂模式结合的好处。

昨天累的要死,晚上还头痛好长时间,今早起来,八点多到自习室,完成昨天没完事的设计模式“策略模式”的研究。

1.初识策略模式

首先还是看看定义吧:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换,策略模式让算法独立于使用它的客户而独立变化。

策略模式包括以下几个部分的内容:

(1)—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。

(2)—具体策略角色:包装了相关的算法和行为。

(3)—环境角色:持有一个策略类的引用,最终给客户端调用。

    学习设计模式也要注重类图,这往往很直观:

2.举例了解策略模式    

  前面从理论上初步了解一下什么是策略模式,想必是不太好理解,现在通过一个例子说明到底什么是设计模式。大家都知道美国和我们中国的交个人所得税的方式是不一样的。这是一个本人认为比较典型的一个策略模式应用的例子,采用策略模式的设计如下:

复制代码
//strategy类
class StrategyInterface
{
    public:
        virtual void execute() = 0;
};
//中国的收税策略
class ConcreteStrategyChina: public StrategyInterface
{
    public:
        virtual void execute()
        {
            cout << "Called ConcreteStrategyChina execute method" << endl;
        }
};
//美国的收税策略
class ConcreteStrategyAmerica: public StrategyInterface
{
    public:
        virtual void execute()
        {
            cout << "Called ConcreteStrategyAmerica execute method" << endl;
        }
};
//策略环境类
class Context
{
    private:
        StrategyInterface *_strategy;
    public:
        Context(StrategyInterface *strategy):_strategy(strategy)
        {
        } 
        void set_strategy(StrategyInterface *strategy)
        {
            _strategy = strategy;
        }
        void execute()
        {
            _strategy->execute();
        }
};
 
复制代码

这时在客户端的使用时是比较方便的,只需要这样:

ConcreteStrategyChina concreteStrategyChina;
ConcreteStrategyAmerica concreteStrategyAmerica;
Context contextA(&concreteStrategyChina);
ContextA.execute();
ContextA.set_strategy(&concreteStrategyAmerica);
ContextA.execute();

那么,使用策略模式有什么好处呢?好处就在于:

(1) 策略模式提供了管理相关的算法族的办法,策略类的等级结构定义了一个算法或行为族,恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。

(2) 策略模式使得算法的使用者就和算法本身分离开来,使得系统易于扩展,当要加入日本的个人所得税收费方式时,只需要在加一个Strategy的子类,并重写execute方法。

(3)从某种角度上讲,能减少测试的工作量,每个算法可以很容易进行单独测试,并且修改一个算法,也不会对其他算法类造成影响。

 

3.策略模式和简单工厂模式联手

但是,基础的策略模式并不是最佳的方法,其实只要和简单工厂模式结合相使用,就能使得客户端“认识”的类减少(只需要认识Context类),进一步减少耦合性,并且也使得客户端中所要做出的逻辑判断(到底用哪个具体策略)转移到工厂类中。这里我们把Context作为工厂类就可以了。看看代码吧:

复制代码
class Context
{
    private:
        StrategyInterface *_strategy;
    public:
        Context(string type)
        {
            switch(type)
            {
            case "美国税收":
                _strategy = new ConcreteStrategyAmerica();break;
            case "中国税收":
                _strategy = new ConcreteStrategyChina();break;
       default:
            }
        }
        void execute()
        {
            _strategy->execute();
        }
};
复制代码

这样在客户端只需要实例化Context类,并传入一个string类型的参数就能达到动态使用各种类的目的,并且客户端只需要认识Context类,这真的是太棒了。实际上在基本的策略模式中,选择所要具体使用的算法的职责还是由客户端承担,这本身没有接触客户端需要选择判断的压力,如果和简单工厂模式结合使用后,选择具体使用的算法的责任就交给了Context类,这就大大的减轻了客户端的责任。

 

4.什么情况下使用策略模式

(1)如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。

(2) 一个系统需要动态地在几种算法中选择一种。那么这些算法可以包装到一个个的具体算法类里面,而这些具体算法类都是一个抽象算法类的子类。换言之,这些具体算法类均有统一的接口,由于多态性原则,客户端可以选择使用任何一个具体算法类,并只持有一个数据类型是抽象算法类的对象。

(3)一个系统的算法使用的数据不可以让客户端知道。策略模式可以避免让客户端接触到的复杂的只与算法有关的数据。

(4) 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。此时,使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句,并体现面向对象设计的概念。、

下面不妨举几个在实际应用中已经使用策略模式的例子:

例1:

想必经常编程序的人基本上都用过这个函数吧public virtual void Sort (IComparer comparer),可以看到Sort方法接收一个IComparer类型的参数,那么这个IComparer接口是做什么用的呢?其实是用来确定排序方式的,例如是从大到小排序还是从小到大排序等。这是conpare具体取值就是动态确定的,并且是一系列算法的集合,所以非常适合策略模式,实际上使用的也是策略模式。

例2:

还比如在玩“极品飞车”这款游戏,那么游戏对车的轮胎是可以更换的,不同的轮胎在高速转弯时有不同的痕迹样式,那么针对“汽车”的配件“轮胎”就要可以变化,而且轮胎和轮胎之间是可以相互替换的,这就是典型的要应用“策略模式”的场景!


内容概要:本文详细记录了对一个Android ARM64静态ELF文件中字符串加密机制的逆向分析过程。该ELF文件的所有字符串均被加密,无法通过常规strings命令或IDA直接识别。作者通过分析发现,加密字符串存储在.rodata段,其解密所需信息(包括密文地址、长度和16位密钥)保存在.data.rel.ro段的40字节描述符中。核心解密函数sub_10F408采用自反的双pass流密码算法,结合固定密钥KEY_TERM(由.data段24字节数据计算得出),实现字节级非线性、位置与长度相关的加密。文章还复现了完整的Python解密脚本,并揭示了该保护机制的本质为代码混淆而非强加密,最终成功批量解密全部956条字符串,暴露程序真实行为,如shell命令模板、设备标识篡改、网络重置等操作。此外,文中还提及未启用的自定义壳框架及其反dump设计。; 适合人群:具备逆向工程基础的安全研究人员、二进制分析人员及对ELF保护技术感兴趣的开发者。; 使用场景及目标:①学习ELF二进制中字符串加密的典型实现方式与逆向突破口;②掌握从结构识别、函数追踪到算法还原的完整逆向流程;③理解“绑定二进制”的完整性校验设计及其局限性;④实践编写IDAPython脚本自动化提取与解密敏感数据。; 阅读建议:此资源以实战案例驱动,不仅展示技术细节,更强调逆向思维与验证方法,建议读者结合IDA调试环境,逐步跟随文中步骤进行动态分析与算法验证,深入理解每一步的推理依据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值