目录
一、关于策略模式
二、设计要求
用户要对已有的文件进行加密处理,请提供几种加密方案。
三、设计实现
针对上述问题,使用策略模式设计若干类。
1.策略
本问题策略接口提供2个方法,分别实现加密和解密,代码如下:
java
package xyz.jangle.design.app.strategy;
import java.io.File;
/**
* 策略
* @author jangle
* @email jangle@jangle.xyz
* @time 2026年10月13日 上午8:01:06
*
*/
public interface EncryptStrategy {
void encryptFile(File file); //加密
String decryptFile(File file); //解密
}
2.具体策略
对于本问题,有两个具体策略StrategyOne和StrategyTwo。
StrategyOne使用加减法进行加解密,StrategyTwo使用异或运算进行加解密。具体代码如下:
StrategyOne:
java
package xyz.jangle.design.app.strategy;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 具体策略1,使用数组进行加法加密
* @author jangle
* @email jangle@jangle.xyz
* @time 2026年10月13日 上午8:02:54
*
*/
public class StrategyOne implements EncryptStrategy {
private String password;
public StrategyOne() {
this.password = "I love this game";
}
public StrategyOne(String password) {
super();
if(password == null || password.length()==0) {
this.password = "I love this game";
}
this.password = password;
}
@Override
public void encryptFile(File file) {
byte[] a = password.getBytes();
byte[] c =new byte[0];
int m = 0;
try(FileInputStream in = new FileInputStream(file)){
long length = file.length();
c = new byte[(int)length];
m = in.read(c);
for(int k=0;k<m;k++) {
int n = c[k]+a[k % a.length]; // 加密
c[k] = (byte) n;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try(FileOutputStream out = new FileOutputStream(file)){
out.write(c, 0, m);
out.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String decryptFile(File file) {
byte[] a = password.getBytes();
long length = file.length();
try (FileInputStream in = new FileInputStream(file)) {
byte[] c = new byte[(int) length];
int m = in.read(c);
for (int k = 0; k < m; k++) {
int n = c[k] - a[k % a.length];
c[k] = (byte) n;
}
return new String(c,0,m);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
StrategyTwo:
java
package xyz.jangle.design.app.strategy;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 具体策略2,使用数组进行异或运算加密
* @author jangle
* @email jangle@jangle.xyz
* @time 2026年10月13日 上午8:23:13
*
*/
public class StrategyTwo implements EncryptStrategy {
private String password;
public StrategyTwo() {
this.password = "I love this game";
}
public StrategyTwo(String password) {
super();
if(password == null || password.length()==0) {
this.password = "I love this game";
}
this.password = password;
}
@Override
public void encryptFile(File file) {
byte[] fileByte =null;
int readLength=0;
byte[] pwdByte = password.getBytes();
int pwdLength = pwdByte.length;
try(FileInputStream in = new FileInputStream(file)){
fileByte = new byte[(int)file.length()];
readLength = in.read(fileByte);
for(int k =0;k< readLength;k++) {
int mm = fileByte[k] ^ pwdByte[k % pwdLength];
fileByte[k]= (byte) mm;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try(FileOutputStream out = new FileOutputStream(file)){
if(fileByte ==null || readLength ==0) {
System.out.println("文件未加密成功");
return;
}
out.write(fileByte, 0, readLength);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String decryptFile(File file) {
byte[] pwdBytes = password.getBytes();
try(FileInputStream in = new FileInputStream(file)){
byte[] fileBytes = new byte[(int) file.length()];
int fileLength = in.read(fileBytes);
for(int k = 0;k<fileLength;k++) {
int mm = fileBytes[k] ^ pwdBytes[k % pwdBytes.length];
fileBytes[k] = (byte) mm;
}
return new String(fileBytes,0,fileLength);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
3.上下文
上下文是EncodeContext类,该类包含策略声明用于保存具体策略的引用的变量(strategy)(通过set方法进行注入具体策略):
代码如下:
java
package xyz.jangle.design.app.strategy;
import java.io.File;
/**
* 上下文
* @author jangle
* @email jangle@jangle.xyz
* @time 2026年10月13日 上午8:42:49
*
*/
public class EncodeContext {
EncryptStrategy strategy;
public void setStrategy(EncryptStrategy strategy) {
this.strategy = strategy;
}
public void encryptFile(File file) {
strategy.encryptFile(file);
}
public String decryptFile(File file) {
return strategy.decryptFile(file);
}
}
四、应用程序
下列应用程序中,Application.java使用策略模式中所涉及的类,使用两种策略分别加密、解密文件A.txt和B.txt。
java
package xyz.jangle.design.app.strategy;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
* @author jangle
* @email jangle@jangle.xyz
* @time 2026年10月13日 上午8:45:21
*
*/
public class Application {
public static void main(String[] args) {
String filePath = "src/xyz/jangle/design/app/strategy";
File fileA = new File(filePath+"/A.txt");
EncodeContext context = new EncodeContext();
context.setStrategy(new StrategyOne("123")); //策略1,使用123作为密钥
context.encryptFile(fileA);
String s;
try(BufferedReader in = new BufferedReader(new FileReader(fileA))){
System.out.println("A文件加密后的内容:");
while((s=in.readLine()) != null){
System.out.println(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("A文件解密后的内容:");
System.out.println(context.decryptFile(fileA));
File fileB = new File(filePath + "/B.txt");
context.setStrategy(new StrategyTwo("321")); //策略2,使用321作为密钥
context.encryptFile(fileB);
try(BufferedReader in = new BufferedReader(new FileReader(fileB))){
System.out.println("B文件加密后的内容:");
while((s=in.readLine()) != null){
System.out.println(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("B文件解密后的内容:");
System.out.println(context.decryptFile(fileB));
}
}
A.txt :
java
123456789
B.txt:
java
987654321
五、执行结果
