设计模式——策略模式

Posted 苹果园dog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——策略模式相关的知识,希望对你有一定的参考价值。

声明:以下内容来源于《大话设计模式》,学习。

策略模式:定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

商场收费策略:正常收费、打折收费、返利收费。

类图如下:

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace 策略模式
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private double moneyTotal = 0d;
        public MainWindow()
        {
            InitializeComponent();
            this.cmbType.ItemsSource = Methods.MoneyMethods;
            this.cmbType.SelectedIndex = 0;
        }

        /// <summary>
        /// 确定
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            CashContext cs = null;
            switch (cmbType.SelectedItem.ToString())
            {
                case Methods.CON_NORMAL:
                    cs = new CashContext(new  CasthNormal());
                    break;
                case Methods.CON_REBATE:
                    cs = new CashContext( new CashRebate("0.8"));
                    break;
                case Methods.CON_RETURN:
                    cs = new  CashContext( new CashReturn(300, 30));
                    break;
            }
            double curTotalPrices = 0d;
            curTotalPrices = cs.GetResult(double.Parse(txtPrice.Text.Trim()) * double.Parse(txtNum.Text.Trim()));
            moneyTotal += curTotalPrices;
            lstboxDetail.Items.Add("单价:"+txtPrice.Text.Trim()+"数量:"+txtNum.Text.Trim()+" "+cmbType.SelectedItem.ToString()+
                "合计:"+curTotalPrices);
            txtTotal.Text = moneyTotal.ToString();

        }

        /// <summary>
        /// 重置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            lstboxDetail.Items.Clear();
            txtPrice.Text = string.Empty;
            txtNum.Text = string.Empty;
            txtTotal.Text = "0";
            moneyTotal = 0d;
        }

    }

    #region 策略模式
    /// <summary>
    /// 抽象算法类
    /// </summary>
    public abstract class Strategy
    {
        public abstract double AcceptCash(double money);
    }

    /// <summary>
    /// 正常收费子类
    /// </summary>
    public class CasthNormal : Strategy
    {
        public override double AcceptCash(double money)
        {
            return money;
        }
    }

    /// <summary>
    /// 打折收费子类
    /// </summary>
    public class CashRebate : Strategy
    {
        private double reBate = 1d;
        public CashRebate(string moneyRebate)
        {
            reBate = double.Parse(moneyRebate);
        }
        public override double AcceptCash(double money)
        {
            return money * reBate;
        }
    }

    /// <summary>
    /// 返利子类
    /// </summary>
    public class CashReturn : Strategy
    {
        private double moneyCondition = 0d;
        private double moneyReturn = 0d;
        public CashReturn(double moneyConditon,double moneyReturn)
        {
            this.moneyCondition = moneyConditon;
            this.moneyReturn = moneyReturn;
        }

        public override double AcceptCash(double money)
        {
            double moneyResult = money;
            if (money >= this.moneyCondition)
            {
                moneyResult = money - Math.Floor(money / moneyCondition) * moneyReturn;
            }
            return moneyResult;
        }
    }

    public class CashContext
    {
        private Strategy cs;
        public CashContext(Strategy cs)
        {
            this.cs = cs;
        }

        public double GetResult(double money)
        {
            return cs.AcceptCash(money);
        }
    }
    #endregion
}
<Window x:Class="策略模式.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="商场收银系统" Height="350" Width="525">
    <Window.Resources>        
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="DicUI.xaml">                    
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
            <Style  TargetType="StackPanel">
                <Setter Property="Orientation" Value="Horizontal"></Setter>
                <Setter Property="Margin" Value="10"></Setter>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Row="0">
            <TextBlock Style="{StaticResource textBlockStyle}">单价:</TextBlock>
            <TextBox x:Name="txtPrice" Style="{StaticResource textboxStyle}"></TextBox>
            <Button Height="{Binding ElementName=txtPrice, Path=Height}" 
                    Width="75"
                    Click="Button_Click_1"
                    >确定</Button>
        </StackPanel>
        <StackPanel Grid.Row="1">
            <TextBlock Style="{StaticResource textBlockStyle}">数量:</TextBlock>
            <TextBox x:Name="txtNum" Style="{StaticResource textboxStyle}"></TextBox>
            <Button Height="{Binding ElementName=txtPrice, Path=Height}" 
                    Width="75"
                    Click="Button_Click_2"
                    >重置</Button>
        </StackPanel>
        <StackPanel Grid.Row="2">
            <TextBlock Style="{StaticResource textBlockStyle}">计算方式:</TextBlock>
            <ComboBox x:Name="cmbType" Height="{Binding ElementName=txtPrice, Path=Height}" Width="{Binding ElementName=txtPrice, Path=Width}"></ComboBox>
        </StackPanel>
        <ListBox Grid.Row="3" x:Name="lstboxDetail">
            
        </ListBox>
        <Grid Grid.Row="4">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"></ColumnDefinition>
                    <ColumnDefinition Width="*"></ColumnDefinition>
                </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Style="{StaticResource textBlockStyle}">总计:</TextBlock>
            <TextBlock Grid.Column="1" Style="{StaticResource textBlockStyle}"
                       HorizontalAlignment="Center"
                       TextAlignment="Center"
                       x:Name="txtTotal"
                       Width="{Binding ElementName=txtPrice, Path=Width}">0</TextBlock>
            </Grid>
        </Grid>
    </Grid>
</Window>

 


 

以上是关于设计模式——策略模式的主要内容,如果未能解决你的问题,请参考以下文章

Redis实现分布式锁(设计模式应用实战)

设计模式策略模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

代码片-策略模式+工厂模式

代码片-策略模式+工厂模式

代码片-策略模式+工厂模式

代码片-策略模式+工厂模式