c# 开放/封闭原则

最近看到一篇关于 开放/封闭原则 的文章:https://blog.csdn.net/weixin_30872337/article/details/98280838

可惜文章里的代码无法运行,所以改写了部分代码,记录下来。

下文采用了策略模式来满足 开放/封闭原则 

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<IDiscountRule> rules = new List<IDiscountRule>
            {
                new DiscountRuleNoDiscount(),
                new DiscountRuleFiveItems(),
                new DiscountRuleTenItems(),
                new DiscountRuleTwentyItems(),
            };

            var shoppingCart = new ShoppingCart(new DiscountCalculator(rules), new List<CartItem>());

            for (int i = 0; i < 12; i++)
            {
                shoppingCart.Add(new CartItem());
            }
            Console.WriteLine("商品数量:" + shoppingCart.ItemCount);
            Console.WriteLine("折扣:" + shoppingCart.GetDiscount());
            Console.ReadLine();
        }
    }

    #region 策略

    /// <summary>
    /// 抽象策略角色(Strategy):这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
    /// </summary>
    public interface IDiscountRule
    {
        decimal Discount { get; }

        bool Match(int itemCount);
    }

    /// <summary>
    /// 具体策略角色(ConcreteStrategy):包装了相关的算法或行为。
    /// </summary>
    public class DiscountRuleTwentyItems : IDiscountRule
    {
        public decimal Discount { get { return 0.5m; } }
        public bool Match(int itemCount) { return itemCount >= 20; }
    }

    public class DiscountRuleFiveItems : IDiscountRule
    {
        public decimal Discount { get { return 0.8m; } }
        public bool Match(int itemCount) { return itemCount >= 5 && itemCount < 10; }
    }

    public class DiscountRuleNoDiscount : IDiscountRule
    {
        public decimal Discount { get { return 1m; } }
        public bool Match(int itemCount) { return itemCount < 5; }
    }
    public class DiscountRuleTenItems : IDiscountRule
    {
        public decimal Discount { get { return 0.9m; } }
        public bool Match(int itemCount) { return itemCount >= 10 && itemCount < 20; }
    }

    #endregion

    /// <summary>
    /// 购物车   环境角色(Context):持有一个策略类的引用,提供给客户端使用。
    /// </summary>
    public class ShoppingCart
    {
        private DiscountCalculator calculate;
        private List<CartItem> list;
        public int ItemCount
        {
            get { return list.Count; }
        }

        public void Add(CartItem cartItem)
        {
            list.Add(cartItem);
        }

        public decimal GetDiscount()
        {
            return calculate.Calculate(list.Count);
        }

        public ShoppingCart(DiscountCalculator calculator, List<CartItem> list)
        {
            this.calculate = calculator;
            this.list = list;
        }
    }

    /// <summary>
    /// 折扣计算器
    /// </summary>
    public class DiscountCalculator
    {
        private readonly List<IDiscountRule> rules;

        /// <summary>
        /// 初始化折扣规则
        /// </summary>
        /// <param name="rules">折扣规则</param>
        public DiscountCalculator(List<IDiscountRule> rules)
        {
            this.rules = rules;
        }

        /// <summary>
        /// 按照规则获取折扣
        /// </summary>
        /// <param name="itemCount">商品数量</param>
        /// <returns></returns>
        public decimal Calculate(int itemCount)
        {
            return this.rules.First(dr => dr.Match(itemCount)).Discount;
        }
    }

    /// <summary>
    /// 商品
    /// </summary>
    public class CartItem
    {

    }

    /// <summary>
    /// 失去扩展性的错误示范
    /// </summary>
    public class ShoppingCart2
    {
        private List<CartItem> _items;

        public decimal GetDiscountPercentage()
        {
            decimal ammount = 0;

           
            if (_items.Count >= 5 && _items.Count < 10)
            {
                ammount = 10;
            }
            else if (_items.Count >= 10 && _items.Count < 15)
            {
                ammount = 15;
            }
            else if (_items.Count >= 15)
            {
                ammount = 25;
            }

            return ammount;
        }

        public void Add(CartItem product)
        {
            
        }

        public void Delete(CartItem product)
        {
            
        }
    }

}
原文地址:https://www.cnblogs.com/aitong/p/12518820.html