• 设计模式


    // 结账基类
    public abstract class CashSuper
    {
        public abstract double acceptCash(double money);
    }
    
    // 正常模式
    public class CashNomal : CashSuper
    {
        public override double acceptCash(double money)
        {
            return money;
        }
    }
    
    // 打 8 折
    public class CashRebate : CashSuper
    {
        private double moneyRebate = 1d;
    
        public CashRebate(string rebate)
        {
            moneyRebate = double.Parse(rebate);
        }
    
        public override double acceptCash(double money)
        {
            return money * moneyRebate;
        }
    }
    
    // 满减
    public class CashReturn : CashSuper
    {
        private double moneyCondition = 0.0d;
        private double moneyReturn = 0.0d;
    
        public CashReturn(string condition, string re)
        {
            moneyCondition = double.Parse(condition);
            moneyReturn = double.Parse(re);
        }
    
        public override double acceptCash(double money)
        {
            if (money < moneyCondition) return money;
    
            return money - Math.Floor(money / moneyCondition) * moneyReturn;
        }
    }
    
    // 调用不同算法的"接口"类
    public class CashContext
    {
        public CashSuper cs = null;
    
        public CashContext(string type)
        {
            switch (type)
            {
                case "正常":
                    cs = new CashNomal();
                    break;
                case "8 折":
                    cs = new CashRebate("0.8");
                    break;
                case "满 200 - 50":
                    cs = new CashReturn("200", "50");
                    break;
                default:
                    break;
            }
        }
    
        public double GetResult(double money)
        {
            if (cs == null) return 0;
    
            return cs.acceptCash(money);
        }
    }
    
    // 业务通过"调用"类实现不同的算法,但内部算法具体如何实现的,外部业务不需要知道
    CashContext CashContextObj = new CashContext(SelectedCostType.Name);
    TotalPrice = CashContextObj.GetResult(double.Parse(CurPrice) * double.Parse(CurMul));
    

    类似与简单工程,同样存在后续业务新增策略时,需要修改 CashContext 类的 CashContext(string type) 的问题,违法对修改封闭的原则;

    例子:

    <Window.Resources>
        <localCommon:BindingProxy x:Key="Proxy" Data="{Binding}" />
    </Window.Resources>
    <Grid Margin="20">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="auto"/>            
        </Grid.RowDefinitions>
        <StackPanel>
            <StackPanel.Resources>
                <Style TargetType="TextBox">
                    <Setter Property="Width" Value="120"/>
                </Style>
                <Style TargetType="StackPanel">
                    <Setter Property="Margin" Value="10"/>
                </Style>
                <Style TargetType="Button">
                    <Setter Property="Margin" Value="10 0"/>
                    <Setter Property="Width" Value="55"/>
                    <Setter Property="Height" Value="25"/>
                    <Setter Property="BorderBrush" Value="Transparent"/>
                    <Setter Property="Background" Value="LightSalmon"/>
                </Style>
            </StackPanel.Resources>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="单价:"/>
                <TextBox Text="{Binding CurPrice, UpdateSourceTrigger=PropertyChanged}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="数量:"/>
                <TextBox Text="{Binding CurMul, UpdateSourceTrigger=PropertyChanged}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="折扣:" />
                <ComboBox ItemsSource="{Binding CostTypeList}" Width="100" Background="Transparent" DisplayMemberPath="Name" SelectedItem="{Binding SelectedCostType}">                    
                </ComboBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
            <Button Content="确定" Uid="Sure"/>
                <Button Content="重置" Uid="Reset"/>
            </StackPanel>
        </StackPanel> 
        <Border Grid.Row="1" BorderBrush="LightGray" BorderThickness="1" Margin="10">
            <ListBox ItemsSource="{Binding VList}" x:Name="lb"> 
                <ListBox.ItemTemplate>
                    <DataTemplate>                        
                        <StackPanel Orientation="Horizontal">
                            <StackPanel.Resources>
                                <localCommon:BindingProxy x:Key="ProxyItem" Data="{Binding}" />
                            </StackPanel.Resources>
                            <StackPanel.ContextMenu>
                                <ContextMenu> 
                                    <MenuItem Header="del" Command="{Binding Source={StaticResource Proxy}, Path=Data.DelCommand}" CommandParameter="{Binding Source={StaticResource ProxyItem}, Path=Data}" />
                                </ContextMenu>
                            </StackPanel.ContextMenu>
                            <TextBlock Text="{Binding Price}" Width="350"/>
                            <TextBlock Text="x"/>
                            <TextBlock Text="{Binding Mul}"/>
                            <TextBlock Text=" 折扣:" Margin="15 0 0 0"/>
                            <TextBlock Text="{Binding Rebate}"/>                        
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>                
            </ListBox>
        </Border>
            
        <StackPanel Grid.Row="2">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="总价:" />
                <TextBlock Text="{Binding TureTotalPrice}" FontSize="19"  />
            </StackPanel>
    
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="折扣后的总价:" />
                <TextBlock Text="{Binding TotalPrice}" FontSize="19"  />
            </StackPanel>                     
        </StackPanel>
    </Grid>
    
    xmal.cs
    public partial class Window7 : Window
    {
        public Window7()
        {
            InitializeComponent();
            this.DataContext = new Window7ViewModel() {};
            AddHandler(Button.ClickEvent, new RoutedEventHandler((this.DataContext as Window7ViewModel).Element_Click));
        }
    }
    
    public class BindingProxy : Freezable
    {
        protected override Freezable CreateInstanceCore()
        {
            return new BindingProxy();
        }
    
        public object Data
        {
            get { return (object)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }
    
        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
    }
    
    public class DelegateCommand : ICommand
    {
        public Action<object> ExecuteCommand = null;
        public Func<object, bool> CanExecuteCommand = null;
        public event EventHandler CanExecuteChanged;
        public DelegateCommand() { }
    
        public DelegateCommand(Action<object> act)
        {
            ExecuteCommand = act;
        }
    
        public bool CanExecute(object parameter)
        {
            if (CanExecuteCommand != null)
            {
                return CanExecuteCommand(parameter);
            }
            else
            {
                return true;                
            }
        }
    
        public void Execute(object parameter)
        {
            if (ExecuteCommand != null) this.ExecuteCommand(parameter);         
        }
    
        public void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null)
            {
                CanExecuteChanged(this, EventArgs.Empty);
            }
        }
    }
    
    public class NotifyPropertyChanged : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        /// <summary>
        /// 属性更改通知
        /// </summary>
        /// <param name="propertyname">属性名称</param>
        public void OnProperty(string propertyname)
        {
            PropertyChangedEventHandler propertychanged = PropertyChanged;
            if (propertychanged != null)
            {
                propertychanged(this, new PropertyChangedEventArgs(propertyname));
            }
        }
    
        /// <summary>
        /// 属性更改通知
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="func">返回属性的lambda表达式</param>
        public void RaisePropertyChange<T>(Expression<Func<T>> func)
        {
            var body = func.Body as MemberExpression;
            if (body != null)
            {
                var propertyinfo = body.Member;
                if (propertyinfo != null)
                {
                    PropertyChangedEventHandler propertychanged = PropertyChanged;
                    if (propertychanged != null)
                    {
                        propertychanged(this, new PropertyChangedEventArgs(propertyinfo.Name));
                    }
                }
            }
        }
    }
    
    public class Window7ViewModel : NotifyPropertyChanged
    {
        private string _CurPrice;
        public string CurPrice
        {
            get { return _CurPrice; }
            set
            {
                _CurPrice = value;
                RaisePropertyChange(() => CurPrice);
            }
        }
    
        private string _CurMul;
        public string CurMul
        {
            get { return _CurMul; }
            set
            {
                _CurMul = value;
                RaisePropertyChange(() => CurMul);
            }
        }
    
        private double _TureTotalPrice = 0.0d;
        /// <summary>
        /// 折扣后的总价格
        /// </summary>
        public double TureTotalPrice
        {
            get { return _TureTotalPrice; }
            set
            {
                _TureTotalPrice = value;
                RaisePropertyChange(() => TureTotalPrice);
            }
        }
    
        private double _TotalPrice = 0.0d;
        /// <summary>
        /// 总价格
        /// </summary>
        public double TotalPrice
        {
            get { return _TotalPrice; }
            set
            {
                _TotalPrice = value;
                RaisePropertyChange(() => TotalPrice);
            }
        }
    
        public ObservableCollection<VItem> _VList;
        /// <summary>
        /// 所有清单
        /// </summary>
        public ObservableCollection<VItem> VList
        {
            get
            {
                if (_VList == null)
                {
                    _VList = new ObservableCollection<VItem>();
                }
                return _VList;
            }
            set
            {
                _VList = value;
                RaisePropertyChange(() => VList);
            }
        }
    
        public ObservableCollection<CostType> _CostTypeList;
        /// <summary>
        /// 所有折扣类型
        /// </summary>
        public ObservableCollection<CostType> CostTypeList
        {
            get
            {
                if (_CostTypeList == null)
                {
                    _CostTypeList = new ObservableCollection<CostType>();
                }
                return _CostTypeList;
            }
            set
            {
                _CostTypeList = value;
                RaisePropertyChange(() => CostTypeList);
            }
        }
    
        public CostType SelectedCostType { get; set; }
    
        public DelegateCommand DelCommand { get; set; }
                    
        public Window7ViewModel()
        {
            DelCommand = new DelegateCommand(new Action<object>(DelItem));
    
            CostTypeList.Add(new CostType() { Name = "正常"});
            CostTypeList.Add(new CostType() { Name = "8 折"});
            CostTypeList.Add(new CostType() { Name = "满 200 - 50"});
        }
    
        private void DelItem(object obj)
        {
            try
            {
                VItem item = obj as VItem;
                VList.Remove(item);
    
                CashContext CashContextObj = new CashContext(item.Rebate);
                TotalPrice -= CashContextObj.GetResult(double.Parse(item.Price) * double.Parse(item.Mul));
                TureTotalPrice -= double.Parse(item.Price) * double.Parse(item.Mul);
            }
            catch (Exception ex)
            {
    
            }
        }
    
        public void Element_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                UIElement element = (UIElement)e.Source;
    
                if (element == null) element = (UIElement)e.OriginalSource;
    
                if (element == null) return;
    
                switch (element.Uid)
                {
                    case "Sure":
                        if (SelectedCostType == null)
                        {                            
                            MessageBox.Show("请选择折扣");
                            return;
                        }
    
                        CashContext CashContextObj = new CashContext(SelectedCostType.Name);
    
                        TotalPrice += CashContextObj.GetResult(double.Parse(CurPrice) * double.Parse(CurMul));
    
                        TureTotalPrice += double.Parse(CurPrice) * double.Parse(CurMul);
    
                        VList.Add(new VItem() { Price = CurPrice, Mul = CurMul,Rebate = SelectedCostType.Name });
    
                        ResetCur();
                        break;
    
                    case "Reset":
                        VList.Clear();
                        ResetCur();
                        TotalPrice = 0;
                        TureTotalPrice = 0;
                        break;
    
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("出错了:" + ex);
            }
        }    
        
        private void ResetCur()
        {
            CurPrice = string.Empty;
            CurMul = string.Empty;
        }
    }
    
    /// <summary>
    /// 新增的每一项
    /// </summary>
    public class VItem : NotifyPropertyChanged
    {
        private string _Price;
        public string Price
        {
            get { return _Price; }
            set
            {
                _Price = value;
                RaisePropertyChange(() => Price);
            }
        }
    
        private string _Mul;
        public string Mul
        {
            get { return _Mul; }
            set
            {
                _Mul = value;
                RaisePropertyChange(() => Mul);
            }
        }
        
        private string _Rebate;
        public string Rebate
        {
            get { return _Rebate; }
            set
            {
                _Rebate = value;
                RaisePropertyChange(() => Rebate);
            }
        }
    }
    
    /// <summary>
    /// 折扣类型
    /// </summary>
    public class CostType
    {
        public string Name { get; set; }
        public double Cost { get; set; }
    }
    
  • 相关阅读:
    JVM类加载的过程
    接口文档设计
    代码规范及CodeReview要点
    Linux权限
    Linux文件
    UltraEdit编辑器基础技巧
    Android环境配置
    JDK 环境配置
    xml没有提示解决办法<eclipse>
    mysql事务实例
  • 原文地址:https://www.cnblogs.com/MichaelLoveSna/p/14141448.html
Copyright © 2020-2023  润新知