🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。 🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏
设计模式(Design Pattern)是软件开发领域的宝贵经验,是多人反复借鉴和广泛应用的代码设计指导。它们是一系列经过分类和归纳的代码组织方法,旨在实现可重用性、可维护性和可理解性。使用设计模式,我们能够编写高质量的代码,使其更易于他人理解,并提供了代码可靠性的保证。
毫无疑问,设计模式对个人、团队和整个系统都带来了显著的益处。它们将代码开发提升到工程化水平,为软件工程构建提供了坚实的基础,就如同大厦的一块块精巧的砖石一样。在项目中明智地应用设计模式可以完美地解决各种复杂问题。每种设计模式都有相应的原理和最佳实践,它们描述了我们日常开发中不断遇到的问题,以及这些问题的核心解决方法。正是因为这种实用性和通用性,设计模式才能在软件开发中广泛地得以应用。设计模式是构建稳健、可扩展和可维护软件的关键工具,为开发者们提供了解决问题的智慧和指导。
策略模式是一种行为型设计模式,它的核心思想是将一系列算法或行为封装成独立的策略类,使得这些策略可以相互替换,而不影响客户端代码的稳定性。这样做的好处是将行为和其所在的环境解耦,使得系统更加灵活、可维护,同时也支持算法的独立变化。
具体来说,策略模式包括以下要点:
策略模式是一种有助于将算法独立于其使用者的设计模式,它将行为封装在各个策略类中,使得系统更加灵活、可维护,并支持动态切换不同的算法。这种模式有助于优化代码结构,提高代码的可读性和可维护性。
策略模式(Strategy Pattern)中的抽象策略(Strategy)是这个模式的核心概念,它定义了一组算法或行为的抽象接口,以及所有具体策略类都必须实现的方法。抽象策略用于定义策略模式的统一接口,以确保所有具体策略类都具备相同的方法签名,从而使这些策略类可以互相替代。
抽象策略的作用包括:
抽象策略在策略模式中充当了一个接口的角色,定义了策略类必须实现的方法,确保了策略类之间的一致性,并使得客户端代码与具体策略的实现相分离,从而实现了算法和客户端的解耦。这种设计有助于提高代码的可维护性、可扩展性和可读性,同时支持动态切换不同的策略。
策略模式(Strategy Pattern)中的具体策略(Concrete Strategy)是实现抽象策略(Strategy)接口或继承抽象策略类的具体类。每个具体策略类都代表了一种不同的算法或行为,它们实现了抽象策略中定义的方法,并为系统提供了多个可替代的算法选择。
具体策略的概念和作用包括:
具体策略在策略模式中代表了具体的算法或行为实现,它们提供了多个可替代的策略选择,使得客户端可以根据需要动态选择不同的策略,从而实现了算法和客户端的解耦,提高了系统的可维护性、可扩展性,并支持动态切换行为。这种模式有助于使代码更具灵活性和可复用性。
策略模式(Strategy Pattern)中的环境类(Context)是一个重要的角色,它担当着管理和使用具体策略(Concrete Strategy)的责任。环境类在策略模式中扮演着协调者的角色,负责与具体策略交互、委派任务以及控制策略的切换。以下是环境类的概念和作用:
环境类在策略模式中充当了一个管理和协调策略的角色。它封装了策略对象,委派任务给具体策略,支持动态切换策略,传递上下文信息,并使客户端与具体策略解耦。这种设计模式有助于提高代码的可维护性、可扩展性,并使系统更加灵活,能够根据需求选择不同的策略来执行特定任务。
命名空间StragetyPattern中包含策略基类Tax以及它的8个实现类,Context环境类持有策略基类。本示例通过一个优雅的方式来计算个人所得税。
public abstract class Tax {
protected decimal TaxRate = 0;
protected decimal QuickDeduction = 0;
public virtual decimal Calculate(decimal income) {
return income * TaxRate - QuickDeduction;
}
}
策略基类Tax,表示个人所得税,TaxRate为税率,QuickDeduction为速算扣除数,Calculate计算相应收入的个人所得税。
public class Level0 : Tax {
public Level0() {
TaxRate = 0.00m;
QuickDeduction = 0;
}
}
0级个人所得税阶梯,表示个人所得税的初始状态。
public class Level1 : Tax {
public Level1() {
TaxRate = 0.03m;
QuickDeduction = 0;
}
}
1级个人所得税阶梯。
public class Level2 : Tax {
public Level2() {
TaxRate = 0.10m;
QuickDeduction = 105;
}
}
2级个人所得税阶梯。
public class Level3 : Tax {
public Level3() {
TaxRate = 0.20m;
QuickDeduction = 555;
}
}
3级个人所得税阶梯。
public class Level4 : Tax {
public Level4() {
TaxRate = 0.25m;
QuickDeduction = 1005;
}
}
4级个人所得税阶梯。
public class Level5 : Tax {
public Level5() {
TaxRate = 0.30m;
QuickDeduction = 2755;
}
}
5级个人所得税阶梯。
public class Level6 : Tax {
public Level6() {
TaxRate = 0.35m;
QuickDeduction = 5505;
}
}
6级个人所得税阶梯。
public class Level7 : Tax {
public Level7() {
TaxRate = 0.45m;
QuickDeduction = 13505;
}
}
7级个人所得税阶梯。
public class Context {
private Tax _tax = null;
private const decimal EXEMPTION_VALUE = 3500m;
private List<decimal> _taxLevel = new List<decimal>{
0,
1500,
4500,
9000,
35000,
55000,
80000,
decimal.MaxValue
};
private List<Type> _levels = new List<Type>();
private void GetLevels() {
_levels = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(tp => tp.GetTypes()
.Where(t => t.BaseType == typeof(Tax)))
.ToList();
}
public Context() {
GetLevels();
}
public Context Calculate(decimal income) {
_tax = new Level0();
var result = income - EXEMPTION_VALUE;
for(int i = 1; i <= _taxLevel.Count - 1; i++) {
if(result > _taxLevel[i - 1] && result <= _taxLevel[i]) {
_tax = (Tax)Activator.CreateInstance(_levels[i]);
}
}
Console.WriteLine($"Income = {income}," + $"tax = {_tax.Calculate(result)}!");
return this;
}
}
环境类Context,首先需要维持对Tax的引用,EXEMPTION_VALUE表示免征额(本例使用3500元),之后通过反射和一些技巧选择相应的Tax实现类来计算相应阶梯的个人所得税。
public class Program {
private static Context _context = new Context();
public static void Main(string[] args) {
_context.Calculate(2500.00m)
.Calculate(4900.00m)
.Calculate(5500.00m)
.Calculate(7000.00m)
.Calculate(10000.00m)
.Calculate(16000.00m)
.Calculate(43000.00m)
.Calculate(70000.00m)
.Calculate(100000.00m)
.Calculate(4500.00m)
.Calculate(1986.00m);
Console.ReadKey();
}
}
以上是调用方的代码,Calculate经过特殊处理以支持方法链。以下是这个案例的输出结果:
Income = 2500.00,tax = 0.0000!
Income = 4900.00,tax = 42.0000!
Income = 5500.00,tax = 95.0000!
Income = 7000.00,tax = 245.0000!
Income = 10000.00,tax = 745.0000!
Income = 16000.00,tax = 2120.0000!
Income = 43000.00,tax = 9095.0000!
Income = 70000.00,tax = 17770.0000!
Income = 100000.00,tax = 29920.0000!
Income = 4500.00,tax = 30.0000!
Income = 1986.00,tax = 0.0000!
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
策略模式(Strategy Pattern)具有以下优点:
策略模式是一种有利于提高代码灵活性、可维护性和可扩展性的设计模式。它允许动态选择算法,将责任分散到具体策略类中,减少了代码的耦合度,使系统更易于维护和测试。这使得策略模式在需要处理多种算法或行为的情况下非常有用。
策略模式(Strategy Pattern)虽然有很多优点,但也存在一些缺点,需要考虑:
策略模式是一种有用的设计模式,但在某些情况下可能不是最佳选择。开发人员需要根据具体的应用场景和需求来权衡策略模式的优点和缺点,以确定是否使用它。对于简单的情景,可能存在更简单的解决方案,而对于复杂的情景,策略模式可以提供更好的灵活性和可维护性。
策略模式(Strategy Pattern)适用于以下场景:
if-else
语句来选择不同的行为,可以考虑使用策略模式来替代这些条件逻辑。策略模式适用于需要在运行时选择不同算法或行为的情况,以及需要降低条件语句复杂度、遵循单一职责原则、提高可扩展性和可维护性的场景。当系统需要支持多种策略或算法时,策略模式是一个有力的设计模式。