场景:
[陕西航天职工大学] 每学期都要根据各科成绩及其它表现评选出部分 三好学生奖、单科成绩优秀奖,思想品德优秀奖等各种奖项。
三好学生评奖主要条件:学习成绩各科平均成绩80分以上,且单科成绩不低于70分;道德表现良好(>=80),包括学年内无旷课,因私事假不超过三天,病假缺勤不超过总课时的5%等。三好学生奖金标准:每人每学期600元。
单科成绩优秀奖主要条件:在未获“三好学生”奖项的学生中,且成绩不低于90分者。单科成绩优秀奖奖金标准:每人每学期100元。
思想品德奖主要条件:学期内各门功课成绩不低于60分,道德表现鉴定为优秀(>=90)。思想品德优秀奖奖金标准:每人每学期100元。
当然这些评选规则一般是固定的,但有时候可能会修改某些奖项条件,可能会增加某些奖项,可能会删除某些奖项。
任务:
请用C#代码,采用Strategy模式近似模拟奖项评选。
UML类图:
上述场景基本类图:
经典Strategy设计模式UML类图参考:
代码演练:
AwardSuper.cs
using System; using System.Collections.Generic; using System.Text; namespace StrategyMode { abstract class AwardSuper
{ public abstract string Award(double courseMark,double moralMark,double gymMark); } }
ThreeGoodAward.cs
using System; using System.Collections.Generic; using System.Text; namespace StrategyMode { class ThreeGoodAward : AwardSuper { public override string Award(double courseMark,double moralMark,double gymMark) { if (courseMark >= 70 && moralMark >= 80 && gymMark >= 70 &&(courseMark+gymMark)/2 >= 80) return "三好学生奖 奖金600元"; else return ""; } } }
CourseAward.cs
using System; using System.Collections.Generic; using System.Text; namespace StrategyMode { class CourseAward :AwardSuper { public override string Award(double courseMark, double moralMark, double gymMark) {
string strTip=""; if (courseMark >= 90) strTip += "课程成绩优秀奖 奖金100元";
if (gymMark >= 90)
strTip += "体育成绩优秀奖 奖金100元"; return strTip; } } }
MoralAward.cs:
using System; using System.Collections.Generic; using System.Text; namespace StrategyMode { class MoralAward :AwardSuper { public override string Award(double courseMark, double moralMark, double gymMark) { if (moralMark >= 90 && moralMark >= 60&&gymMark >= 60) return "思想品德优秀奖 奖金100元"; else return ""; } } }
AwardContext.cs:
using System; using System.Collections.Generic; using System.Text; namespace StrategyMode { class AwardContext { private AwardSuper aws; public AwardContext(AwardSuper asuper) { this.aws=asuper; } public string GetResult(double courseMark, double moralMark, double gymMark) { return aws.Award(courseMark,moralMark,gymMark); } }
}
Program.cs:
using System; namespace StrategyMode { class Program { static void Main(string[] args) { AwardContext cc = null; string strSel = string.Empty; Console.WriteLine("请选择奖励种类:"); strSel=Console.ReadLine(); switch(strSel) { case "three": cc = new AwardContext(new ThreeGoodAward()); break; case "course": cc = new AwardContext(new CourseAward()); break; case "moral": cc = new AwardContext(new MoralAward()); break; } Console.WriteLine("请输入Course Mark:"); string courseMark = Console.ReadLine(); Console.WriteLine("请输入Moral Mark:"); string moralMark = Console.ReadLine(); Console.WriteLine("请输入Gym Mark:"); string gymMark = Console.ReadLine(); string strResult = cc.GetResult(Convert.ToDouble(courseMark),Convert.ToDouble(moralMark), Convert.ToDouble(gymMark)); Console.WriteLine(strResult); } } }
深度总结:
主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。意图:定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。
如何解决:将这些算法封装成一个一个的类(或者通过工厂)来实现任意地替换。
优点:
- 1、算法可以自由切换。
- 2、单独封装的算法便于单元测试。
- 3、避免使用多重条件判断。
- 4、扩展性良好(每一个策略相当于一个类,减少依赖,松耦合)。
缺点:
- 1、策略类会增多。
- 2、所有策略类都需要对外暴露。