策略模式

策略模式的结构中包含3种角色:策略(Strategy)、上下文(Context
、具体策略(ConcreteStrategy)
策略模式具有以下优点:
1.上下文(Context)和具体策略(ConcreteStrategy)是松耦合关系
因此上下文只知道它要使用Strategy接口类的实例,但不需要知道
具体是哪一个类。
2.策略模式满足“开-闭”原则。当增加新的具体原则时,
不需要修改上下文类的代码,上下文就可以引用新的具体策略的实例。
适合使用策略模式的情景:
1.一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件
语句的形式出现,那么可以使用策略模式避免在类中使用大量的条件语
句。
2.程序的主要类(相当于上下文的角色)不希望暴露复杂的、
与算法相关的数据结构,那么可以使用策略模式封装算法,
即算法分别封装到具体策略中。
3.需要使用一个算法的不同变体。

例一:

策略接口:

public interface Strategy {
    public double computerAverage(double a[]);
}

实现策略接口的具体策略A:
public class ConcreteStrategyA implements Strategy{
    @Override
    public double computerAverage(double a[]) {
        double sum = 0, score = 0;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
        }
        score = sum / a.length;
        return score;
    }
}

实现策略接口的具体策略B:
public class ConcreteStrategyB  implements Strategy{
    @Override
    public double computerAverage(double a[]) {
        if (a.length <= 2)
            return 0;
        double sum = 0, score = 0;
        for (int i = 1; i < a.length-1; i++) {
            sum += a[i];
        }
        score = sum / (a.length - 2);
        return score;
    }
}

人:
class Person {
    String name;
    double score;
    public void setScore(double t) {
        score = t;
    }
    public void setName(String s) {
        name = s;
    }
    public double getScore() {
        return score;
    }
    public String getName() {
        return name;
    }
}

选择策略:
public class AverageScore {
    Strategy strategy;
    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }
    public double getAverage(double a[]) {
        if(strategy != null) {
            return strategy.computerAverage(a);
        } else {
            System.out.println("没有求平均值的方法,得到的-1不代表平均值");
            return -1;
        }
    }
}

Main主类:
public class Main {
    public static void main(String[] args) {
         AverageScore game = new AverageScore();
         game.setStrategy(new ConcreteStrategyA());
         Person wang = new Person();
         wang.setName("王建");
         double [] a = {9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.0};
         double aver = game.getAverage(a);
         wang.setScore(aver);
         System.out.println("算法A:");
         System.out.printf("%s的最后得分是%5.3f%n", wang.getName(), wang.getScore());

         game.setStrategy(new ConcreteStrategyB());
         aver = game.getAverage(a);
         wang.setScore(aver);
         System.out.println("算法B:");
         System.out.printf("%s的最后得分是%5.3f", wang.getName(), wang.getScore());
    }
}

例二:

策略接口:
import java.io.File;

public interface EncryptStrategy {
    public void setPassword(String s);
    public abstract void encryptFile(File file);
    public abstract String decryptFile(File file);
}

实现策略接口的具体策略一:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class StrategyOne implements EncryptStrategy{

    String password;

    @Override
    public void setPassword(String s) {
        password = s;
    }

    @Override
    public void encryptFile(File file) {

        try {
            File tempFile = new File("C:\\Users\\Administrator\\Desktop\\temp.txt");
            byte [] secret = password.getBytes();
            FileInputStream in = new FileInputStream(file);
            FileOutputStream out = new FileOutputStream(tempFile);
            int n = secret.length, m = -1;
            byte [] content = new byte[n];
            while((m = in.read(content, 0, n)) != -1) {
                for (int k = 0; k < m; k++) {
                    content[k] = (byte)(content[k] + secret[k]);//加密
                }
                out.write(content, 0, m);//将加密写入临时文件
            }
            in.close();
            out.close();
            in = new FileInputStream(tempFile);
            out = new FileOutputStream(file);
            byte [] c = new byte[10];
            while ((m = in.read(c, 0, 10))!= -1) {
                out.write(c, 0, m);  //加密文件替换原来的文件
            }
            tempFile.delete();
            in.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }       
    }

    @Override
    public String decryptFile(File file) {

        try {
            byte [] a = password.getBytes();
            long length = file.length();
            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;
            }       
            in.close();
            return new String(c);
        } catch (Exception e) {
            return e.toString();
        }   
    }
}

实现策略接口的具体策略二:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class StrategyTwo implements EncryptStrategy {

    String password;

    @Override
    public void setPassword(String s) {
        password = s;
    }

    @Override
    public void encryptFile(File file) {
        try {
            File tempFile = new File("C:\\Users\\Administrator\\Desktop\\temp.txt");
            byte[] secret = password.getBytes();
            FileInputStream in = new FileInputStream(file);
            FileOutputStream out = new FileOutputStream(tempFile);
            int n = secret.length, m = -1;
            byte[] content = new byte[n];
            while ((m = in.read(content, 0, n)) != -1) {
                for (int k = 0; k < m; k++) {
                    content[k] = (byte) (content[k] ^ secret[k]);// 加密
                }
                out.write(content, 0, m);// 将加密写入临时文件
            }
            in.close();
            out.close();
            in = new FileInputStream(tempFile);
            out = new FileOutputStream(file);
            byte[] c = new byte[10];
            while ((m = in.read(c, 0, 10)) != -1) {
                out.write(c, 0, m); // 加密文件替换原来的文件
            }
            tempFile.delete();
            in.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public String decryptFile(File file) {

        try {
            byte [] a = password.getBytes();
            long length = file.length();
            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;   //解密
            }       
            in.close();
            return new String(c);
        } catch (Exception e) {
            return e.toString();
        }   
    }
}

选择策略:
import java.io.File;

public class EncodeContext {
    EncryptStrategy strategy;
    public void setStrategy(EncryptStrategy strategy) {
        this.strategy = strategy;
    }
    public void encryptFile(File file) {
        if (strategy != null) {
            strategy.encryptFile(file);
        } else {
            System.out.println("没有加密策略可用!!");
        }
    }
    public String decryptFile(File file) {
        if (strategy != null) {
            return strategy.decryptFile(file);
        } else {
            return "";
        }
    }
}

Main主类:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class Main {
    public static void main(String[] args) {
        File fileOne = new File("C:\\Users\\Administrator\\Desktop\\A.txt");
        File fileTwo = new File("C:\\Users\\Administrator\\Desktop\\B.txt");
        EncodeContext encode = new EncodeContext(); //上下文对象
        EncryptStrategy one = new StrategyOne();
        String password = "xuzifeng";
        one.setPassword(password);
        encode.setStrategy(one);  //上下文对象使用策略一 
        encode.encryptFile(fileOne);
        System.out.println(fileOne.getName() + "加密后的内容:");
        String s = "";
        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 (Exception e) {
            e.printStackTrace();
        }

        String str = encode.decryptFile(fileOne);
        System.out.println(fileOne.getName() + "解密后的内容:");
        System.out.println(str);


        EncryptStrategy two = new StrategyTwo();
        password = "wangjian";
        two.setPassword(password);
        encode.setStrategy(two);  //上下文对象使用策略二
        encode.encryptFile(fileTwo);
        System.out.println(fileTwo.getName() + "加密后的内容:");
        try {
            FileReader inOne = new FileReader(fileTwo);
            BufferedReader inTwo = new BufferedReader(inOne);
            while((s = inTwo.readLine()) != null) {
                System.out.println(s);
            }
            inOne.close();
            inTwo.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        str = encode.decryptFile(fileTwo);
        System.out.println(fileTwo.getName() + "解密后的内容:");
        System.out.println(str);        
    }
}

参考:https://www.cnblogs.com/dotgua/p/strategy-pattern.html
https://www.cnblogs.com/java-my-life/archive/2012/05/10/2491891.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值