序言:设计模式是程序设计中非常重要,也是非常关键的步骤。若能在程序设计中恰当地应用设计模式的思想,那么代码的质量和可维护性将会大大的提升,同时对我们的编码水平也是一种提升。
目录
一、概述
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
策略模式的定义是:定义算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。这算法体现了几个设计原则,第一、把变化的代码从不变的代码中分离出来;第二、针对接口编程而不是具体类(定义了策略接口);第三、多用组合,少用继承(客户通过组合方式使用策略)。
二、结构类图
图片引用自:https://www.runoob.com/design-pattern/strategy-pattern.html
三、应用场景
1.如果一个系统里有很多类,他们只是某个行为不同时,使用策略模式可以让一个对象在许多行为中选择一种行为。
2.一个系统需要动态地在几种算法中选择一种。
3.有多重转移条件语句考虑使用策略模式。
例如:在中国,知识产权局为了鼓励企业多多投入科技创新,每年都会对有申请知识产权保护的企业进行经济补助,而知识产权有很多分类,比如说:专利、商标、软件著作权等等。对于不同类型的知识产权,资助的金额标准也是不同的。因此正好可以使用策略模式,每个知识产权类型对应一个资助标准。
四、代码示例
Fund.java 政府资助接口
/**
* 政府资助接口
*/
interface Fund {
void fund();
}
PatentStrategy.java 专利资助策略
/**
* 资助专利
*/
class PatentStrategy implements Fund{
@Override
public void fund() {
System.out.println("专利每年资助5000元");
}
}
TrademarkStrategy.java 商标资助策略
/**
* 资助商标
*/
class TrademarkStrategy implements Fund{
@Override
public void fund() {
System.out.println("商标每件资助1000元");
}
}
SoftwareCopyrightStrategy.java 软件著作权资助策略
/**
* 资助软件著作权
*/
class SoftwareCopyrightStrategy implements Funding{
@Override
public void fund() {
System.out.println("软件著作权每件资助3000元");
}
}
IPR.java 知识产权对象类
class IPR<T extends Fund>{
public Fund fundStrategy;
public IPR(T fundStrategy){
this.fundStrategy = fundStrategy;
}
public void getFund(){
fundStrategy.fund();
}
}
StrategyClient,java 测试类
/**
* Created by Viking on 2019/9/22
* 策略模式案例
* 知识产权资助改进版(使用泛型)
*/
public class StrategyClientImproved {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
IPR2 patent = new IPR(new PatentStrategy());
IPR2 trademark = new IPR(new TrademarkStrategy());
IPR2 softwareCopyright = new IPR(new SoftwareCopyrightStrategy());
patent.getFund();
trademark.getFund();
softwareCopyright.getFund();
}
}
运行结果:
专利每件资助5000元
商标每件资助1000元
软件著作权每件资助3000元
五、策略模式的优缺点
1.优点
(1).体现了“对修改关闭,对扩展开放”原则,客户端增加行为不用修改原有代码,只要添加一种策略即可。
(2).避免了使用多重转移语句(if..else if..else)。
(3).提供了可以替换继承关系的办法: 继承提供了另一种支持多种算法或行为的方法。你可以直接生成一个Context类的子类,从而给它以不同的行为。但这会将行为硬行编制到 Context中,而将算法的实现与Context的实现混合起来,从而使Context难以理解、难以维护和难以扩展,而且还不能动态地改变算法。最后你得到一堆相关的类 , 它们之间的唯一差别是它们所使用的算法或行为。 将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使它易于切换、易于理解、易于扩展。
2.缺点
(1).每添加一个策略就要增加一个类,当策略过多是会导致类数目庞大。
(2).客户端需明确知道系统有哪些策略可以使用,当策略过多时客户端的学习成本较高。
本文是在参考学习了前辈大佬的分享的基础上,结合自己的理解和看法,重新整理了一些有自己看法的笔记。
注:文章引用部分均出自:https://www.cnblogs.com/jenkinschan/p/5645300.html