zoukankan      html  css  js  c++  java
  • 设计模式四:策略模式

    策略模式
    所谓策略其实就是做一件事情有很多很多的方法,比如说一个商场要搞促销,促销的方式有可能有很多:打折啊,满100返50啊、积分等等之类的。这种不同的促销方式在我们系统中表示就是一个一个的策略,并且策略是可以随时更换的,这个时候在设计系统时就可以使用策略模式。
    商场有可能会更换或追加新的促销模式,也就是策略存在调整,也就是会更改以前的代码,为了满足开闭原则,这时就要使用抽象类和接口,这里我们偏向使用接口。在接口里面定义策略的方法,根据不同的情况编写不同的实现类,实现不同的策略,策略模式比较适用于算法经常变化的情况,比如计算工资的方式、出行方式的选择等等。

    如图所示,我们先定义策略的接口(Promotion),然后在这个策略接口里定义策略的方法(GetPrice()),接着我们定义了两种具体的策略(Discount打折)和(MoneyBack返现)。
    策略模式会专门有一个上下文对象(PromotionContext)专门管理策略类,并且上下文对象和策略接口之间是聚合的关系,也就是整体和部分的关系,因此在上下文对象里应该保存一个促销类型的引用,另外上下文对象里一般会有一些方便客户端调用的方法,如GetPrice()。客户端程序可以通过上下文对象得到价格,这个GetPrice()里会根据不同的策略,执行不同的策略方法。
    如果客户端不想使用上下文中定义的默认的策略,也可以去修改策略类,因为上下文中有一个ChangePromotion()的方法,客户端主要使用上下文对象,如果需要修改策略,他还要依赖于具体的策略对象。

    示例:

    1、策略接口:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 策略模式
     8 {
     9     /*
    10        策略接口
    11      */
    12     public interface IPromotion
    13     {
    14         /// <summary>
    15         /// 根据原价和策略计算新价格
    16         /// </summary>
    17         /// <param name="originPrice">原价</param>
    18         /// <returns></returns>
    19         double GetPrice(double originPrice);
    20     }
    21 }

    2、Discount打折策略类

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 策略模式
     8 {
     9     /// <summary>
    10     /// 打折策略类
    11     /// </summary>
    12    public  class Discount :IPromotion
    13     {
    14 
    15         public double GetPrice(double originPrice)
    16         {
    17             Console.WriteLine("打八折:");
    18             return originPrice * 0.8;
    19         }
    20     }
    21 }

    3、MoneyBack返现类

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 策略模式
     8 {
     9     /*
    10      返现策略类:满100返50的策略
    11      */
    12     class MoneyBack :IPromotion
    13     {
    14         public double GetPrice(double originPrice)
    15         {
    16             Console.WriteLine("满100返50");
    17             return originPrice - (int)originPrice / 100 * 50;
    18         }
    19     }
    20 }

    4、策略上下文类

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 策略模式
     8 {
     9     /*
    10      策略上下文,为客户选择合适的策略
    11      */
    12    public  class PromotionContext
    13     {
    14        private IPromotion p = null;
    15 
    16        public PromotionContext(IPromotion p)
    17        {
    18            this.p = p;
    19        }
    20 
    21        public double GetPrice(double originPrice)
    22        {
    23            // 默认策略
    24            if (this.p == null)
    25            {
    26                this.p = new Discount();
    27            }
    28            return this.p.GetPrice(originPrice);
    29        }
    30 
    31        /// <summary>
    32        /// 更改策略的方法
    33        /// </summary>
    34        /// <param name="p"></param>
    35        public void ChangePromotion(IPromotion p)
    36        {
    37            this.p = p;
    38        }
    39     }
    40 }

    5、主程序调用

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 策略模式
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             // 默认策略:打八折的策略
    14             PromotionContext pc = new PromotionContext(null);
    15             Console.WriteLine(pc.GetPrice(200)) ;
    16 
    17             // 更改策略:满100返50的策略
    18             pc.ChangePromotion(new MoneyBack());
    19             Console.WriteLine(pc.GetPrice(155.9));
    20             Console.ReadKey();
    21         }
    22     }
    23 }

     代码连接地址:http://files.cnblogs.com/files/dotnet261010/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.rar

  • 相关阅读:
    Maximum Flow Exhaustion of Paths Algorithm
    ubuntu下安装java环境
    visualbox使用(二)
    vxworks一个超级奇怪的错误(parse error before `char')
    February 4th, 2018 Week 6th Sunday
    February 3rd, 2018 Week 5th Saturday
    February 2nd, 2018 Week 5th Friday
    February 1st, 2018 Week 5th Thursday
    January 31st, 2018 Week 05th Wednesday
    January 30th, 2018 Week 05th Tuesday
  • 原文地址:https://www.cnblogs.com/dotnet261010/p/7355397.html
Copyright © 2011-2022 走看看