设计模式-策略者模式

1、定义

    策略模式是针对一组算法,将每一个算法封装到具备公共接口的独立的类中,从而使它们能够相互替换。策略模式使得算法能够在不影响到客户端的状况下发生变化。算法

 

2、UML类图

image

 

3、例子展现

namespace 策略者模式
{
    public interface ITaxStrategy
    {
        double GetTax(double money);
    }

    public class PersnalStrategy : ITaxStrategy
    {
        public double GetTax(double money)
        {
            return money * 0.1;
        }
    }

    public class EnterpriseTaxStrategy : ITaxStrategy
    {
        public double GetTax(double money)
        {
            return (money - 4000) > 0 ? (money - 4000) * 0.045 : 0.0;
        }
    }

    public class TaxContext
    {
        private ITaxStrategy _strategy;

        public TaxContext(ITaxStrategy taxStrategy)
        {
            _strategy = taxStrategy;
        }

        public double GetTax(double money)
        {
            return _strategy.GetTax(money);
        }
    }

    public class Client
    {
        public static void Process()
        {
            TaxContext taxContext = new TaxContext(new PersnalStrategy());
            double tax = taxContext.GetTax(10000);
            Console.WriteLine("我的所得税:"+tax);

             taxContext = new TaxContext(new EnterpriseTaxStrategy());
             tax = taxContext.GetTax(100000);
            Console.WriteLine("企业所得税:" + tax);

            // 与简单工厂模式一块儿,避免客户端既依赖于TaxContext,又依赖于具体策略者。这样客户端只须要知道TaxContext就能够了
            TaxContext2 taxContext2 = new TaxContext2("PersnalStrategy");
            double tax2 = taxContext2.GetTax(10000);
            Console.WriteLine("升级版 我的所得税:" + tax2);

            taxContext2 = new TaxContext2("EnterpriseTaxStrategy");
            tax2 = taxContext2.GetTax(100000);
            Console.WriteLine("升级版 企业所得税:" + tax2);
        }
    }

    public class TaxContext2
    {
        private ITaxStrategy _strategy;

        /// <summary>
        /// 简单工厂一块儿
        /// </summary>
        /// <param name="taxType"></param>
        public TaxContext2(string taxType)
        {
            switch (taxType)
            {
                case "PersnalStrategy":
                    _strategy = new PersnalStrategy();
                    break;
                case "EnterpriseTaxStrategy":
                    _strategy = new EnterpriseTaxStrategy();
                    break;
                default:
                    break;
            }
        }

        public double GetTax(double money)
        {
            return _strategy.GetTax(money);
        }
    }
}
View Code

4、项目中实际用到

咱们是作在线练习系统。其中有个功能模块,判断试题的对错。对于不一样的题型:单选、多选、判断、填空、解答,判断对错的算法不一样,可是本质都是要获得这道题是否正确。ide

首先咱们能够抽象出一个获得对错的算法接口,即策略者类:函数

public interface IJudgeCorrect<TDoQuestion>
{
    bool DoJugeCorrect(TDoQuestion doQuestion);
} 
View Code

 

接下来写各类不一样题型获得对错的类,具体策略者类:this

// 判断选择题的策略者

public class JudgeChoiceQuestionCorrect : IJudgeCorrect<DoQuestion>
{
    public bool DoJugeCorrect(DoQuestion doQuestion)
    {
        if (string.IsNullOrEmpty(doQuestion.Answer))
        {
            return false;
        }

        // 对Answer按照abcd的顺序排序,有可能从前台传来的数据不对
        if (doQuestion.Answer.Length > 1)
        {
            var answerarray = doQuestion.Answer.ToCharArray().OrderBy(p => p).ToArray();
            doQuestion.Answer = new string(answerarray);
        }

        return doQuestion.Question.Answer.Trim() == doQuestion.Answer.Trim();
    }
}

 

// 判断题策略者类

public class JudgeTrueFalseQuestionCorrect : IJudgeCorrect<DoQuestion>
{
    public bool DoJugeCorrect(DoQuestion doQuestion)
    {

        if (string.IsNullOrEmpty(doQuestion.Answer))
        {
            return false;
        }

        return doQuestion.Question.Answer.Trim() == doQuestion.Answer.Trim();
    }
} 
View Code

 

其余题型再也不一一列举。spa

 

和简单工厂联合,获得具体策略者。code

public class JudgeCorrectFactory : IJudgeCorrectFactory<Question,DoQuestion>
    {
        private  Dictionary<QuestionMode, IJudgeCorrect<DoQuestion>> _factoties = new Dictionary<QuestionMode, IJudgeCorrect<DoQuestion>>();

        public  IJudgeCorrect<DoQuestion> CreateJudgeCorrect(Question question)
        {
            IJudgeCorrect<DoQuestion> jugeCorrect = null ;

            switch (question.QuestionMode)
            {
                case QuestionMode.SingleChoice:
                case QuestionMode.DoubleChoice:
                case QuestionMode.MultipleChoice:
                    if (_factoties.Keys.Contains(QuestionMode.SingleChoice))
                    {
                        jugeCorrect = _factoties[QuestionMode.SingleChoice];
                    }
                    else
                    {
                        jugeCorrect = new JudgeChoiceQuestionCorrect();
                        _factoties.Add(QuestionMode.SingleChoice, jugeCorrect);
                    }                  
                    break;
                case QuestionMode.TrueFalse:
                    if (_factoties.Keys.Contains(QuestionMode.TrueFalse))
                    {
                        jugeCorrect = _factoties[QuestionMode.TrueFalse];
                    }
                    else
                    {
                        jugeCorrect = new JudgeTrueFalseQuestionCorrect();
                        _factoties.Add(QuestionMode.TrueFalse, jugeCorrect);
                    }
                    break;
                case QuestionMode.FillBlank:
                    if (_factoties.Keys.Contains(QuestionMode.FillBlank))
                    {
                        jugeCorrect = _factoties[QuestionMode.FillBlank];
                    }
                    else
                    {
                        jugeCorrect = new JudgeFillBlankQuestionCorrect();
                        _factoties.Add(QuestionMode.FillBlank, jugeCorrect);
                    }
                    break;
                case QuestionMode.Discuss:
                    if (_factoties.Keys.Contains(QuestionMode.Discuss))
                    {
                        jugeCorrect = _factoties[QuestionMode.Discuss];
                    }
                    else
                    {
                        jugeCorrect = new JudgeDiscussQuestionCorrect();
                        _factoties.Add(QuestionMode.Discuss, jugeCorrect);
                    }
                    break;
                case QuestionMode.Complex:
                    if (_factoties.Keys.Contains(QuestionMode.Complex))
                    {
                        jugeCorrect = _factoties[QuestionMode.Complex];
                    }
                    else
                    {
                        jugeCorrect = new JudgeComplexQuestionCorrect(this);
                        _factoties.Add(QuestionMode.Complex, jugeCorrect);
                    }
                    break;
                default:
                    throw new Exception("获取判断试卷参数错误!");
            }

            return jugeCorrect;
        }
    }
View Code

 

具体应用上下文中,经过构造函数传入工厂:blog

public SubmitStudyInfo(TDbContext dbContext, IJudgeCorrectFactory<Question, DoQuestion> jugeCorrectFactory)
       {
           _jugeCorrectFactory = jugeCorrectFactory;
           _dbContext = dbContext;
       } 
View Code

 

5、总结

策略者模式主要是对算法的封装,把一系列算法封装到策略者类中,从而能够是不一样的策略类自由切换并且避免了在代码中写不少if 或者switch。排序

相关文章
相关标签/搜索