Java常用设计模式--策略模式(Strategy Pattern)
时间:2022-07-23
本文章向大家介绍Java常用设计模式--策略模式(Strategy Pattern),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
简介
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
策略模式角色
- 环境(Context)角色:持有一个Strategy的引用,最终给客户端调用。
- 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
例子
比如说常见的会员体系,普通会员,黄金会员,白金会员...
示例代码
package com.example.strategy;
public interface Member {
void show();
}
package com.example.strategy;
/**
* 普通会员
*/
public class CommonMember implements Member{
@Override
public void show() {
System.out.println("我是普通会员");
}
}
package com.example.strategy;
/**
* 黄金会员
*/
public class GoldMember implements Member{
@Override
public void show() {
System.out.println("我是黄金会员");
}
}
package com.example.strategy;
/**
* 白金会员
*/
public class PlatinaMember implements Member{
@Override
public void show() {
System.out.println("我是白金会员");
}
}
package com.example.strategy;
public class Context {
private Member member;
public Context(Member member) {
this.member = member;
}
public void doAction(){
this.member.show();
}
// 动态替换算法(策略)
public void replaceStrategy(Member member) {
this.member = member;
}
}
package com.example.strategy;
public class Test {
public static void main(String[] args) {
Member commonMember = new CommonMember();
Member goldMember = new GoldMember();
Member platinaMember = new PlatinaMember();
//普通会员
Context context = new Context(commonMember);
context.doAction();
//切换策略类为黄金会员
context.replaceStrategy(goldMember);
context.doAction();
//切换策略类为白金会员
context.replaceStrategy(platinaMember);
context.doAction();
}
}
策略模式的优缺点
1、优点
- 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。具体策略类实现自同一个接口,他们之间可以自由切换
- 良好的扩展性。增加一种策略,只要实现接口,写上具体逻辑就可以了。当旧策略不需要时,直接剔除就行。
- 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
2、缺点
- 如果策略增多,策略类的数量就会增加,维护各个策略类会给带来额外开销,策略类太多时,消耗更大。
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。也就是各个策略需要暴露给客户端。
- MySQL和Oracle中的隐式转换(r6笔记第45天)
- R语言的数据导入与导出(write.table,CAT)
- gqlplus的简单使用(r6笔记第43天)
- Java基础-21(01)总结字符流,IO流编码问题,实用案例必做一遍
- zabbix中配置dg的监控(r6笔记第62天)
- Apache ActiveMQ 远程代码执行漏洞 (CVE-2016-3088)分析
- mysql5.5与mysq 5.6中禁用innodb引擎的方法
- 缓慢的update语句性能分析(r6笔记第61天)
- 一个dg警告发现的硬件问题 (r6笔记第60天)
- mysql几种存储引擎介绍
- Java基础-21(02)总结字符流,IO流编码问题,实用案例必做一遍
- DeDeCMS v5.7 密码修改漏洞分析
- Java基础-20(01)总结,递归,IO流
- 一个Oracle bug的手工修复(r6笔记第59天)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- AndroidStdio1_2
- 使用扩展技术对SAP Fiori应用进行端到端的增强,一个实际案例介绍
- python Unhandled exception in event loop:错误解决
- SAP Fiori image的显示原理
- 解决Error:All flavors must now belong to a named flavor dimension.
- 同时搞定Android和iOS的Dart语言(3):数值类型
- SAP Fiori图标(icon)设计原理
- SAP Fiori应用发生超时错误的一个可能原因
- 如何用云开发快速搭建实时 Todo List 应用
- Angular应用的入口
- Angular里的structural directive的一个例子
- Angular条件指令ngIf的一个例子
- Angular的property binding一个例子
- Angular里的按钮事件注册方法一例
- 如何使用Angular的@Input()装饰器