这篇文章主要讲解了“怎么理解Java设计模式的策略模式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解Java设计模式的策略模式”吧!
策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数。
策略模式定义和封装了一系列的算法,它们是可以相互替换的,也就是说它们具有共性,而它们的共性就体现在策略接口的行为上,另外为了达到最后一句话的目的,也就是说让算法独立于使用它的客户而独立变化,我们需要让客户端依赖于策略接口。
一种很简单的解释,在我们的开发过程中,经常会遇到大量的if...else或者switch...case语句,当这些语句在开发中只是为了起到分流作用,这些分流和业务逻辑无关,那么这个时候就可以考虑用策略模式。
这个模式涉及到三个角色:
上下文环境(Context
)角色:持有一个Strategy的引用。
抽象策略(Strategy
)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
具体策略(ConcreteStrategy
)角色:包装了相关的算法或行为
举一个例子,商场搞促销--打8折,满200送50,满1000送礼物,这种促销就是策略。
再举一个例子,dota里面的战术,玩命四保一,三伪核体系,推进体系,大招流体系等,这些战术都是一种策略。
应用场景:
1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
优点:
1、结构清晰,把策略分离成一个个单独的类「替换了传统的 if else」2、代码耦合度降低,安全性提高「各个策略的细节被屏蔽」
缺点:
1、客户端必须要知道所有的策略类,否则你不知道该使用那个策略,所以策略模式适用于提前知道所有策略的情况下2、策略类数量增多(每一个策略类复用性很小,如果需要增加算法,就只能新增类)五、策略模式和简单工厂模式的异同
在上篇文章已经提过了,传送地址:深入理解设计模式(二):简单工厂模式
Strategy
类,定义所有支持的算法的公共接口
//Strategy类,定义所有支持的算法的公共接口
abstract class Strategy
{
//算法方法
public abstract void AlgorithmInterface();
}
oncreteStrategy
,封装了具体的算法或行为,继承于Strategy
//算法A
class ConcreteStrategyA : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("算法A的实现");
}
}
//算法B
class ConcreteStrategyB : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("算法B的实现");
}
}
//算法C
class ConcreteStrategyC : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("算法C的实现");
}
}
Context
,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用
//Context,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用
class Context
{
Strategy Strategy;
public Context(Strategy Strategy)
{
this.Strategy = Strategy;
}
//上下文接口
public void ContextInterface()
{
Strategy.AlgorithmInterface();
}
}
客户端代码
static void Main(string[] args)
{
Context Context;
Context = new Context(new ConcreteStrategyA());
Context.ContextInterface();
Context = new Context(new ConcreteStrategyB());
Context.ContextInterface();
Context = new Context(new ConcreteStrategyC());
Context.ContextInterface();
Console.Read();
}
改造后的Context
class Context
{
Strategy Strategy=null;
public Context(string type)
{
switch (type)
{
case "A":
ConcreteStrategyA A = new ConcreteStrategyA();
Strategy = A;
break;
case "B":
ConcreteStrategyB B = new ConcreteStrategyB();
Strategy = B;
break;
case "C":
ConcreteStrategyC C = new ConcreteStrategyC();
Strategy = C;
break;
}
}
//上下文接口
public void ContextInterface()
{
Strategy.AlgorithmInterface();
}
}
改造后的客户端代码
static void Main(string[] args)
{
Context Context = new Context("这里是相应的算法类型字符串");
Context.ContextInterface();
Console.Read();
}
对比下改造前后的区别不难看出,改造前客户端需要认识两个类,Context和ConcreteStrategy。而策略模式和简单工厂模式结合后,客户端只需要认识一个类Context,降低了耦合性。
我们可以使用枚举在一个类中实现以上所有的功能及三种不同的角色,下面看看怎么通过枚举来实现策略模式
public enum Calculator
{ ADD("+") {
public int exec(int a, int b) {
return a+b;
}
},
SUB("-") {
public int exec(int a, int b) {
return a-b;
}
};
public abstract int exec(int a, int b);
//运算符
private String value = "";
private Calculator(String value)
{
this.value = value;
}
public String getValue()
{
return value;
}
}
在枚举类中,定义的抽象方法就像当时之前的接口,每一个枚举ADD SUB相当是一个具体的实现类(策略角色),而整个枚举类就是策略的分装角色。
感谢各位的阅读,以上就是“怎么理解Java设计模式的策略模式”的内容了,经过本文的学习后,相信大家对怎么理解Java设计模式的策略模式这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。