Java的设计模式(5)-- 策略模式
定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换,本模式使得算法可以独立于使用它的客户而变化。策略模式包括以下三种角色
- 策略(Strategy):策略是一个接口,该接口定义若干个算法标识,定义了若干个抽象方法。
- 具体策略(ConcreteStrategy):具体策略是实现策略接口的类,具体策略实现策略接口所定义的抽象方法,给出算法标识的具体算法。
- 上下文(Context):上下文是依赖策略接口的类,即上下文包含有策略声明的变量。上下文中提供一个方法,该方法委托策略变量调用具体策略所实现的策略接口中方法。
策略模式的UML类图如下图所示:
策略模式的优点:
上下文和具体策略是松耦合的关系,上下文只知道它要使用某一个实现Strategy接口类的实例,但不需要知道具体是哪一类。
策略模式满足“开-闭原则”。当增加新的具体策略时,不需要修改上下文类的代码,上下文就可以引用新的具体策略实例。
策略模式的使用场景:
一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件语句的形式出现,那么可以使用策略模式避免在类中使用大量的条件语句。
程序不希望暴露复杂的。与算法相关的数据结构,可以使用策略模式封装算法。
需要使用一个算法的不同实体。
应用举例 —— 加密、解密文件
用户需要对已有的文件进行加密处理,请提供几种加密方案。
设计实现可以使用策略模式,具体如下:
1. 策略接口的名称是EncryptStrategy,该接口有两个抽象方法,一个是加密,一个是解密
public interface EncryptStrategy {
public abstract void encryptFile(File file);
public abstract void decryptFile(File file);
}
2. 具体策略,有两个具体策略,StrategyONE和StrategyTWO
- StrategyONE使用一个字符串做密码,比如password,将这个字符串编码到一个字节数组,byte[] e = password.getBytes(); 假设e的长度是n,那么就将文件内容以n字节为一组,对每组中字节,用数组e对应字节做加法运算,解密的话就是相应的做减法运算。
- StrategyTWO使用一个字符串做密码,比如password,将这个字符串编码到一个字节数组,byte[] e = password.getBytes(); 假设e的长度是n,那么就将文件内容按顺序以n字节为一组对每组中字节,使用数组e的对应字节做异或运算
public class StrategyOne implements EncryptStrategy {
String password; public StrategyOne(String password) {
if(password == null||password.trim().length()==0)
this.password = "I love java";
this.password = password;
}
public StrategyOne() {
this.password = "I love java";
}
public void encryptFile(File file) {
try {
byte[] a = this.password.getBytes();
FileInputStream fis = new FileInputStream(file);
long length = file.length();
byte[] c = new byte[(int)length];
int m = fis.read();
for (int i = 0; i < m; i++) {
int n = c[i]+a[i%a.length];
c[i] = (byte) n;
}
fis.close();
FileOutputStream fos = new FileOutputStream(file);
fos.write(c, 0, m);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
} public void decryptFile(File file) {
try {
byte[] a = this.password.getBytes();
FileInputStream fis = new FileInputStream(file);
long length = file.length();
byte[] c = new byte[(int)length];
int m = fis.read();
for (int i = 0; i < m; i++) {
int n = c[i]-a[i%a.length];
c[i] = (byte) n;
}
fis.close();
FileOutputStream fos = new FileOutputStream(file);
fos.write(c, 0, m);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
public class StrategyTWO implements EncryptStrategy {
String password; public StrategyTWO(String password) {
if(password == null||password.trim().length()==0)
this.password = "I love java";
this.password = password;
}
public StrategyTWO() {
this.password = "I love java";
}
@Override
public void encryptFile(File file) {
try {
byte[] a = this.password.getBytes();
FileInputStream fis = new FileInputStream(file);
long length = file.length();
byte[] c = new byte[(int)length];
int m = fis.read();
for (int i = 0; i < m; i++) {
int n = c[i]^a[i%a.length];
c[i] = (byte) n;
}
fis.close();
FileOutputStream fos = new FileOutputStream(file);
fos.write(c, 0, m);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public void decryptFile(File file) {
try {
byte[] a = this.password.getBytes();
FileInputStream fis = new FileInputStream(file);
long length = file.length();
byte[] c = new byte[(int)length];
int m = fis.read();
for (int i = 0; i < m; i++) {
int n = c[i]^a[i%a.length];
c[i] = (byte) n;
}
fis.close();
FileOutputStream fos = new FileOutputStream(file);
fos.write(c, 0, m);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 上下文,该类包含策略声明用于保存具体策略的引用变量,代码如下
public class EncodeContext { public EncryptStrategy strategy; public void setStrategy(EncryptStrategy strategy) {
this.strategy = strategy;
} public void encryptFile(File file){
this.strategy.encryptFile(file);
} public void decryptFile(File file){
this.strategy.decryptFile(file);
}
}
4. 应用程序
public class Application {
public static void main(String[] args) {
File fileOne = new File("A.txt"); String s = "";
EncodeContext con = new EncodeContext();
con.setStrategy(new StrategyOne("Hello world!"));
con.encryptFile(fileOne);
System.out.println(fileOne.getName()+"加密后的內容:");
try {
FileReader inOne = new FileReader(fileOne);
BufferedReader inTwo = new BufferedReader(inOne);
while((s=inTwo.readLine())!=null){
System.out.println(s);
}
inOne.close();
inTwo.close();
} catch (IOException e) {
e.printStackTrace();
} }
}
Java的设计模式(5)-- 策略模式的更多相关文章
- Java的设计模式----strategy(策略模式)
设计模式: 一个程序员对设计模式的理解: “不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开 ...
- [java之设计模式]策略模式
策略模式(strategy pattern) 定义>> 将一系列的算法封装到一些列的类里面,并且可以相互替换 作用>> 将算法的变化独立于客户端,将算法的指责和算法的行为分开, ...
- 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查
原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...
- [design-patterns]设计模式之一策略模式
设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不 ...
- 设计模式:策略模式(Strategy)
定 义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...
- PHP设计模式之策略模式
前提: 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查 找.排序等,一种常用的方法是硬编码(Hard Cod ...
- JavaScript设计模式之策略模式(学习笔记)
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
- 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)
原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...
- JavaScript设计模式之策略模式
所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...
- 设计模式入门,策略模式,c++代码实现
// test01.cpp : Defines the entry point for the console application.////第一章,设计模式入门,策略模式#include &quo ...
随机推荐
- CF1208题解
C \(\begin{aligned}\ 0 0 1 1\\ 0 0 1 1\\ 2 2 3 3\\ 2 2 3 3\\ \end{aligned}\)将每个四方格分别加上\(0,4,8,12\) D ...
- NOIP(划掉)CSP2019一轮知识点
今年似乎变动很大呢…… 去年总结的 历年真题 以下标题中打*的是我认为的重点内容 *一.关于计算机 (一)计算机组成 计算机的工作原理跟人的大脑很相似,而且还是大脑功能的延伸,所以习惯上叫它电脑. 硬 ...
- Spring boot Security 登陆安全配置
实现的效果 访问url时,如果未登录时跳转到Login界面,要求用户登陆,如果登陆过返回请求的数据. 效果图 访问数据时,未登录返回login界面 登陆操作 登陆成功进入登出界面 登陆成功后再次访问数 ...
- vue 错误提问示例
> 表格显示数据,选中其中一条数据进行编辑,弹出层编辑,发现修改数据时,表格中的数据同步变化.编辑成功之后,还会返回原本没修改之前的数据. > 传对象给子组件,子组件的值污染父组件.
- Git Bash基础使用(初始化)
前提是在码云上已经新建一个空的项目,可参考:https://www.cnblogs.com/babysbreath/p/9170455.html 1.新建一个目录,存放下载下来的项目,我在D盘新建了一 ...
- 深度学习面试题16:小卷积核级联卷积VS大卷积核卷积
目录 感受野 多个小卷积核连续卷积和单个大卷积核卷积的作用相同 小卷积核的优势 参考资料 感受野 在卷积神经网络中,感受野(Receptive Field)的定义是卷积神经网络每一层输出的特征图(fe ...
- https://pingcap.com/blog-cn/flame-graph/
https://pingcap.com/blog-cn/flame-graph/ 因为 TiKV 是自己内部使用了 jemalloc,并没有用系统的 malloc,所以我们不能直接用 perf 来探查 ...
- button按钮的状态为disabled禁用状态,click事件无法触发,但是为什么touchstart下却依然可以触发
切换到移动模拟模式,并点击按钮,查看控制台. 发现click没有事件没有触发,而touch事件依然触发. 解决办法: 对于移动端我们使用css来禁止按钮,达到disable的效果: 对,就是这个神奇的 ...
- seekBar拖动滑块
中秋节学习,, 通过拖动滑块,改变图片的透明度 <?xml version="1.0" encoding="utf-8"?> <LinearL ...
- tr -d命令删除与字符无关的符号
echo "/192.168"| tr -d '/' 结果:192.168