zoukankan      html  css  js  c++  java
  • 设计模式-策略模式详解

    一、引言

    在讲策略模式之前,我们来看零售行业软件的一个针对客户类型打折的功能。

    vip客户打八折,svip客户打七折。

    代码实现:

     if (customer == "vip")
     {
           amount = amount * 0.8;
     }
     else if (customer == "svip")
     {
           amount = amount * 0.7;
     }

    看代码,挺简单的,但是如果今天vip打八折,明天要打7折,那还得改变原有的代码,这样就违背了开闭原则。这里变化的是折扣的计算方式(策略),策略模式就可以解决这类问题。

    二、概念

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

    三、实现

    策略模式包含三种角色:Context: 上下文类、Strategy: 抽象策略类、ConcreteStrategy: 具体策略类

    抽象策略类:

        public abstract class AbstractDiscountStrategy
        {
            public abstract decimal Discount(decimal amount);
        }

    具体策略类:

        public class VipDiscountStrategy:AbstractDiscountStrategy
        {
            public override decimal Discount(decimal amount)
            {
                return amount * 0.8M;
            }
        }
        public class SVipDiscountStrategy:AbstractDiscountStrategy
        {
            public override decimal Discount(decimal amount)
            {
                return amount * 0.7M;
            }
        }

    环境类:

       public class StrategyContext
        {
            private AbstractDiscountStrategy discountStrategy;
    
            public StrategyContext(AbstractDiscountStrategy concreteDiscountStrategy)
            {
                this.discountStrategy = concreteDiscountStrategy;
            }
    
            public decimal ExecuteStrategy(decimal amount)
            {
                return this.discountStrategy.Discount(amount);
            }
        }

    调用:

     if (customer == "vip")
                {
                    context = new StrategyContext(new VipDiscountStrategy());
                    amount = context.ExecuteStrategy(amount);
                }
                else if (customer == "svip")
                {
                    context = new StrategyContext(new SVipDiscountStrategy());
                    amount = context.ExecuteStrategy(amount);
                }

    可以看到,应用策略模式后,如果要修改vip客户的折扣计算方式,只需要修改对应的策略即可,不需要修改客户端的调用代码,也不会影响到svip的折扣计算方式,符合开闭原则。

    再来一个ssvip客户,只需要增加一个对应的策略实现类,并且修改客户端的调用方法即可。

    vip和svip的策略可以互换。

    四、总结

    从上面的例子可以看出来,策略模式的优点是提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。

    缺点也很明显,客户端必须清楚知道每一个策略的用途,并且自行决定使用哪一个策略,增加了客户端的负担,这个问题可以使用配置的方式来解决。每一个策略都需要一个类,会使策略类增多。

    代码下载:https://github.com/hzhhhbb/StrategyPattern

  • 相关阅读:
    异常 集中异步处理
    客户端获取服务端自定义类数据 z
    客户端使用自定义代理类访问WCF服务 z
    学习“要件审判九步法”,正确处理五个关系 z
    “要件审判九步法”具体步骤
    要件审判九步法及其基本价值 z
    WCF Windows Service Using TopShelf and ServiceModelEx z
    [ACM_数据结构] Color the ball [线段树水题][数组开大]
    [ACM_数据结构] HDU 1166 敌兵布阵 线段树 或 树状数组
    [ACM_数据结构] 线段树模板
  • 原文地址:https://www.cnblogs.com/hzhhhbb/p/11538083.html
Copyright © 2011-2022 走看看