[设计模式] 策略模式(Strategy)

简介:

reference to : http://www.cnblogs.com/spring5/archive/2011/10/20/2485291.html

一、概要
我们构建程序的时候,会遇到这样的状况,对象有某个行为,但是在不同的场景中,使用策略模式,可以把它们一个个封装起来,并且使它们可相互替换,而起使得算法可独立于使用它的客户而变化。
 
二、生活举例
对于一个商店来讲,对不同的客户要报不同的价格,比如:
(1)对普通客户或者是新客户报的是全价
(2)对老客户(会员)报的价格,要给予一定的折扣
(3)对大客户(批发)报的价格,根据大客户购买量,给予一定的折扣
(4)根据不同的时间段,例如工作日和节假日等,可能价格仍然不同。
处理复杂的报价功能,就会用到策略模式。
 
三、实现思路

 

 

四、类图

 

五、注意点
1、策略模式的设计原则即把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为。
2、策略模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户,即把会变化的内容取出并封装起来,以便以后可以轻易地改动或扩充部分,而不影响不需要变化的其他部分;这样便可以动态的改变对象的行为。
 
六、实例
1、说明:通过策略模式,简单工厂+策略模式,反射+策略模式三种方式实现需求,然后对比三种实现方式。
2、语言:C#
3、虚拟需求:《机房收费系统》计费方式:1、学生周一到周五免费 2、学生周六,周日1元/小时 3、临时用户任何时间都是1.5元/小时

代码1.0(策略模式标准实现):

复制代码
using System;

namespace 策略模式
{
    class Program
    {
        private string type;
        public Program(string type)
        {
            this.type = type;
        }
        static void Main(string[] args)
        {

            Program pro = new Program("学生,周一到周五");
            //Program pro = new Program("学生,周六周日");
            //Program pro = new Program("临时用户,任意时间");
            switch (pro.type)           
            {
                case "学生,周一到周五":
                    Contest c1 = new Contest(new concreteStrategyA());
                    c1.ContestInterface();
                    break;
                case "学生,周六周日":
                    Contest c2 = new Contest(new concreteStrategyB());
                    c2.ContestInterface();
                    break;
                case "临时用户,任意时间":
                     Contest c3 = new Contest(new concreteStrategyC());
                    c3.ContestInterface();
                    break;
            }
        }
    }
    abstract class Strategy
    {
        //算法方法
        public abstract void AlgorithmInterface();

    }

    //具体算法:学生周一到周五免费
    class concreteStrategyA : Strategy
    {
        //算法A实现方法
        public override void AlgorithmInterface()
        {
            Console.WriteLine("学生周一到周五免费");
        }
    }
    //具体算法:学生周六,周日1元/小时
    class concreteStrategyB : Strategy
    {
        //算法B实现方法
        public override void AlgorithmInterface()
        {
            Console.WriteLine("学生周六,周日1元/小时");
        }
    }

    //具体算法:临时用户任何时间都是1.5元/小时
    class concreteStrategyC : Strategy
    {
        //算法C实现方法
        public override void AlgorithmInterface()
        {
            Console.WriteLine("临时用户任何时间都是1.5元/小时");
        }
    }

    class Contest
    {
        Strategy strategy;
        public Contest(Strategy strategy)
        {
            this.strategy = strategy;
        }
        //上下文接口
        public void ContestInterface()
        {
            strategy.AlgorithmInterface();
        }
    }
}
复制代码

代码2.0(策略模式+简单工厂):

复制代码
<span style="color:#000000;">using System;

namespace 策略模式和简单工厂结合
{
    class Program
    {
        static void Main(string[] args)
        {
            Contest c1 = new Contest("学生,周一到周五");
            c1.ContestInterface();
            Contest c2 = new Contest("学生,周六周日");
            c2.ContestInterface();
            Contest c3 = new Contest("临时用户,任意时间");
            c3.ContestInterface();       
        }
    }
    abstract class Strategy
    {
        //算法方法
        public abstract void AlgorithmInterface();
      
    }

    //具体算法:学生周一到周五免费
    class concreteStrategyA : Strategy
    {
        //算法A实现方法
        public override void AlgorithmInterface()
        {
            Console.WriteLine("学生周一到周五免费");
        }
    }
    //具体算法:学生周六,周日1元/小时
    class concreteStrategyB : Strategy
    {
        //算法B实现方法
        public override void AlgorithmInterface()
        {
            Console.WriteLine("学生周六,周日1元/小时");
        }
    }

    //具体算法:临时用户任何时间都是1.5元/小时
    class concreteStrategyC : Strategy
    {
        //算法C实现方法
        public override void AlgorithmInterface()
        {
            Console.WriteLine("临时用户任何时间都是1.5元/小时");
        }
    }

    class Contest
    {
        Strategy strategy;
        public Contest(string type)
        {
            switch (type)
            {
                case "学生,周一到周五":
                    concreteStrategyA a = new concreteStrategyA();
                    strategy = a;
                    break;
                case "学生,周六周日":
                    concreteStrategyB b = new concreteStrategyB();
                    strategy = b;
                    break;
                case "临时用户,任意时间":
                    concreteStrategyC c = new concreteStrategyC();
                    strategy = c;
                    break;
            }
        }
        //上下文接口
        public void ContestInterface()
        {
            strategy.AlgorithmInterface();
        }

    }
}</span>
复制代码

代码3.0(策略模式+反射):

 

复制代码
<span style="color:#000000;">using System;
using System.Reflection;

namespace 策略模式和反射结合
{
    class Program
    {
        static void Main(string[] args)
        {
            Contest c1= new Contest("concreteStrategyA");
            c1.ContestInterface();
            Contest c2 = new Contest("concreteStrategyB");
            c2.ContestInterface();
            Contest c3 = new Contest("concreteStrategyC");
            c3.ContestInterface();
        }
    }
    abstract class Strategy
    {
        //算法方法
        public abstract void AlgorithmInterface();

    }

    //具体算法:学生周一到周五免费
    class concreteStrategyA : Strategy
    {
        //算法A实现方法
        public override void AlgorithmInterface()
        {
            Console.WriteLine("学生周一到周五免费");
        }
    }
    //具体算法:学生周六,周日1元/小时
    class concreteStrategyB : Strategy
    {
        //算法B实现方法
        public override void AlgorithmInterface()
        {
            Console.WriteLine("学生周六,周日1元/小时");
        }
    }

    //具体算法:临时用户任何时间都是1.5元/小时
    class concreteStrategyC : Strategy
    {
        //算法C实现方法
        public override void AlgorithmInterface()
        {
            Console.WriteLine("临时用户任何时间都是1.5元/小时");
        }
    }

    class Contest
    {
        private string type;
        Strategy strategy;

        public Contest(string Type)
        {
            this.type = Type;
            //利用反射技术生成类的实例
            strategy = (Strategy)Assembly.Load("策略和反射").CreateInstance("策略模式和反射结合." + this.type);
        }

        //上下文接口
        public void ContestInterface()
        {
            strategy.AlgorithmInterface();
        }

    }
}</span>
复制代码

三种实现方式的比较:

发现代码1.0和代码2.0的主要区别,前者把Switch分支判断放在了客户端,后者利用工厂模式把Switch语句移到了contest中。

显然代码2.0隔离了客户端与具体的算法类,代码有一定优势。

但是,如果我们需要增加一种算法,比如‘教职工免费’,无论代码1.0还是代码2.0,都必须要更改switch代码,这不符合我们的开闭原则。面对同样的需求,当然是改动越小越好。

我们看到代码3.0中用反射技术屏蔽掉了switch语句。这样我们再增加新算法就不必修改context类。从这个角度上说,所有用简单工厂的地方,都可以考虑用反射技术去除选择语句,解除分支语句判断带来的耦合。

 

七、何时选用策略模式 

1、出现有许多相关的类,仅仅是行为有差别的情况,可以使用策略模式来使用多个行为中的一个来配置一个类的方法,实现算法动态切换。

2、出现同一个算法,有很多不同的实现的情况,可以使用策略模式来把这些“不同的实现”实现成为一个算法的类层次。

3、需要封装算法中,与算法相关的数据的情况,可以使用策略模式来避免暴露这些跟算法相关的数据结构。

4、出现抽象一个定义了很多行为的类,并且是通过多个if-else语句来选择这些行为的情况,可以使用策略模式来代替这些条件语句。

综上,策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要再不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

 

八、总结

策略模式属于对象行为型模式,主要针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。通常,策略模式适用于当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。

 

分类:  设计模式
本文转自demoblog博客园博客,原文链接http://www.cnblogs.com/0616--ataozhijia/p/7602897.html如需转载请自行联系原作者

demoblog
相关文章
|
16天前
|
设计模式 算法 测试技术
PHP中的设计模式:策略模式的应用与实践
在软件开发的浩瀚海洋中,设计模式如同灯塔,指引着开发者们避开重复造轮子的暗礁,驶向高效、可维护的代码彼岸。今天,我们将聚焦于PHP领域中的一种重要设计模式——策略模式,探讨其原理、应用及最佳实践,揭示如何通过策略模式赋予PHP应用灵活多变的业务逻辑处理能力,让代码之美在策略的变换中熠熠生辉。
|
7天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
策略模式是一种行为型设计模式,用于定义一系列算法,将每种算法都封装起来,并使它们可以互换。本文将探讨如何在PHP中实现策略模式,以及如何利用它来提高代码的灵活性和可维护性。通过具体示例,我们将看到策略模式在处理复杂业务逻辑时的优势,从而帮助开发者编写出更加清晰、易于扩展的代码。
|
6天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
在软件开发的广袤领域中,PHP以其灵活性和广泛的应用场景占据了一席之地。本文聚焦于PHP中的一个核心概念——设计模式,特别是策略模式。策略模式作为一种行为型设计模式,允许在运行时选择算法或操作的具体实现,为软件设计带来了极大的灵活性。本文将深入探讨策略模式的基本原理、应用场景以及在PHP中的具体实现方式,旨在帮助开发者更好地理解和运用这一设计模式,提升代码的可维护性和扩展性。
10 2
|
8天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与应用
本文将详细探讨PHP中的策略模式,从基本概念到实际应用进行深入分析。通过具体代码示例和应用场景,帮助读者理解并掌握这一设计模式的使用,提升软件开发的灵活性和维护性。
|
17天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入探索与实践在软件开发的广袤天地中,PHP以其独特的魅力和强大的功能,成为无数开发者手中的得力工具。而在这条充满挑战与机遇的征途上,设计模式犹如一盏明灯,指引着我们穿越代码的迷雾,编写出更加高效、灵活且易于维护的程序。今天,就让我们聚焦于设计模式中的璀璨明珠——策略模式,深入探讨其在PHP中的实现方法及其实际应用价值。
策略模式,这一设计模式的核心在于它为软件设计带来了一种全新的视角和方法。它允许我们在运行时根据不同情况选择最适合的解决方案,从而极大地提高了程序的灵活性和可扩展性。在PHP这门广泛应用的编程语言中,策略模式同样大放异彩,为开发者们提供了丰富的创作空间。本文将从策略模式的基本概念入手,逐步深入到PHP中的实现细节,并通过一个具体的实例来展示其在实际项目中的应用效果。我们还将探讨策略模式的优势以及在实际应用中可能遇到的挑战和解决方案,为PHP开发者提供一份宝贵的参考。
|
19天前
|
设计模式 运维 算法
Java设计模式-策略模式(15)
Java设计模式-策略模式(15)
|
26天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深度解析
在PHP开发中,策略模式是一种行为设计模式,它允许你在运行时根据不同情况选择不同的算法或行为。本文将深入探讨策略模式的定义、结构、使用场景以及在PHP中的实现方法,并通过实例展示如何在PHP项目中应用策略模式来提高代码的灵活性和可维护性。
|
27天前
|
设计模式 人工智能 算法
PHP中的设计模式:策略模式的深入解析与实践软件测试中的人工智能革命:提升效率与准确性的新篇章
在PHP开发中,理解并运用设计模式是提升代码质量和可维护性的重要途径。本文聚焦于策略模式(Strategy Pattern),一种行为型设计模式,它允许在运行时选择算法或业务规则。通过本文,我们将深入探讨策略模式的定义、结构、使用场景以及如何在PHP项目中有效地实现和利用策略模式。不同于性能优化等技术性摘要,本文着重于提供对策略模式全面而实用的理解,助力开发者编写出更加灵活和可扩展的应用程序。 本文深入探讨了人工智能在软件测试领域的应用,揭示了其如何显著提高测试过程的效率和准确性。通过实际案例分析,展示了AI技术在自动化测试、缺陷检测及结果分析中的关键作用,并讨论了实施AI测试策略时面临的挑
18 3
|
19天前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与应用在软件开发的浩瀚海洋中,PHP以其独特的魅力和强大的功能吸引了无数开发者。作为一门历史悠久且广泛应用的编程语言,PHP不仅拥有丰富的内置函数和扩展库,还支持面向对象编程(OOP),为开发者提供了灵活而强大的工具集。在PHP的众多特性中,设计模式的应用尤为引人注目,它们如同精雕细琢的宝石,镶嵌在代码的肌理之中,让程序更加优雅、高效且易于维护。今天,我们就来深入探讨PHP中使用频率颇高的一种设计模式——策略模式。
本文旨在深入探讨PHP中的策略模式,从定义到实现,再到应用场景,全面剖析其在PHP编程中的应用价值。策略模式作为一种行为型设计模式,允许在运行时根据不同情况选择不同的算法或行为,极大地提高了代码的灵活性和可维护性。通过实例分析,本文将展示如何在PHP项目中有效利用策略模式来解决实际问题,并提升代码质量。
|
28天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的应用与实践
在软件开发中,设计模式是解决问题的最佳实践。本文将探讨PHP中的策略模式,通过实际应用案例,展示如何有效地使用策略模式来提高代码的灵活性和可维护性。我们将从基本概念入手,逐步深入到实际编码,最终实现一个具有策略模式的应用。