Strategy策略

针对问题

针对特定问题具有多种算法时,我们需要根据上下文随时切换策略,这时运用strategy模式就能良好地组织代码关系,实现灵活选择和切换。

例子

1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。
2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
3、JAVA AWT 中的 LayoutManager。

解决方法

定义一个算法的接口。每一个算法用一个类来表示,均实现这一个接口,客户端针对接口编写程序。

优点

1、算法可以自由切换。
2、避免使用多重条件判断。
3、扩展性良好。

缺点

1、策略类会增多。
2、所有策略类都需要对外暴露。

类图

在这里插入图片描述

实例展示

我们想要比较java读写文件策略中Channel策略、Stream策略和读写器策略三种策略的性能,就运用策略模式。首先设置一个接口,定义算法。

package iostrategy;

public interface Strategyforio {
  /**
   * Read File.
   * 
   * @param filename Path to file to read.
   * @return The result of reading.
   */
  
  public String myread(String filename)throws Exception;
  /**
   * Write File.
   * 
   * @param outString String to write to file.
   * @param filename Path to file to write.
   */
  
  public void mywrite(String outString,String filename)throws Exception;
}

然后分别定义各个策略的类来实现这个接口。
Channel策略:

package iostrategy;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class Channel implements Strategyforio {

  @Override
  public String myread(String filename) throws Exception {
    // TODO 自动生成的方法存根
    long starttime = System.currentTimeMillis();
    StringBuilder result = new StringBuilder();
    try {
      FileInputStream f1 = new FileInputStream(filename); 
      FileChannel fc1 = f1.getChannel();
      ByteBuffer b1 = ByteBuffer.allocate(1024);//初始化缓冲区大小
      while (fc1.read(b1) != -1) {
        int temp = b1.limit();
        b1.flip();
        while (temp != 0 && b1.hasRemaining()) {
          result.append((char)b1.get());
        }
        b1.clear();
      }
      fc1.close();
      f1.close();
    } catch (Exception e) {
      // TODO: handle exception
      throw new Exception(e.toString());
    }
    long endtime = System.currentTimeMillis();
    System.out.println("Channel策略读文件花费了:" + (endtime - starttime) + "ms");
    return result.toString();
  }

  @Override
  public void mywrite(String outString, String filename) throws Exception {
    // TODO 自动生成的方法存根
    long starttime = System.currentTimeMillis();
    try {
      FileOutputStream f1 = new FileOutputStream(filename);
      FileChannel fc1 = f1.getChannel();
      ByteBuffer buffer = ByteBuffer.wrap(outString.getBytes());
      fc1.write(buffer);
      fc1.close();
      f1.close();
    } catch (FileNotFoundException e) {
      // TODO 自动生成的 catch 块
      throw new Exception(e.toString());
    } catch (IOException e) {
      // TODO: handle exception
      throw new Exception(e.toString());
    }
    long endtime = System.currentTimeMillis();
    System.out.println("Channel策略写文件花费了:" + (endtime - starttime) + "ms");
  }
}

Stream策略:

package iostrategy;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Stream implements Strategyforio {

  @Override
  public String myread(String filename) throws Exception {
    // TODO 自动生成的方法存根
    long starttime = System.currentTimeMillis();
    StringBuilder astringBuilder = new StringBuilder();
    try {
      FileInputStream f1 = new FileInputStream(filename);
      byte [] b = new byte[1024];
      int n = 0;
      while ((n = f1.read(b)) != -1) { // 当n不等于-1,则代表未到末尾
        astringBuilder.append(new String(b, 0, n));
      }
      f1.close();
    } catch (FileNotFoundException e) {
      // TODO: handle exception
      throw new Exception(e.toString());
    } catch (IOException e) {
      // TODO: handle exception
      throw new Exception(e.toString());
    }
    long endtime = System.currentTimeMillis();
    System.out.println("Stream策略读文件花费了:" + (endtime - starttime) + "ms");
    return astringBuilder.toString();
  }

  @Override
  public void mywrite(String outString, String filename) throws Exception {
    // TODO 自动生成的方法存根
    long starttime = System.currentTimeMillis();
    try {
      FileOutputStream f1 = new FileOutputStream(filename);
      byte[] b = outString.getBytes();
      f1.write(b);
      f1.close();
    } catch (FileNotFoundException e) {
      // TODO: handle exception
      throw new Exception(e.toString());
    } catch (IOException e) {
      // TODO: handle exception
      throw new Exception(e.toString());
    }
    long endtime = System.currentTimeMillis();
    System.out.println("Stream策略写文件花费了:" + (endtime - starttime) + "ms");
  }
}

读写器策略:

package iostrategy;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class WriterandReader implements Strategyforio {

  @Override
  public String myread(String filename) throws Exception {
    // TODO 自动生成的方法存根
    long starttime = System.currentTimeMillis();
    StringBuilder restfile = new StringBuilder();
    String temp = "";
    BufferedReader myRead;
    try {
      myRead = new BufferedReader(new FileReader(filename));
      while ((temp = myRead.readLine()) != null) {
        restfile.append(temp);
      }
      myRead.close();
    } catch (FileNotFoundException e) {
      // TODO 自动生成的 catch 块
      throw new Exception(e.toString());
    } catch (IOException e) {
      // TODO 自动生成的 catch 块
      throw new Exception(e.toString());
    }
    long endtime = System.currentTimeMillis();
    System.out.println("Reader/Writer策略读文件花费了:" + (endtime - starttime) + "ms");
    return restfile.toString();
  }

  @Override
  public void mywrite(String outString, String filename) throws Exception {
    // TODO 自动生成的方法存根
    long starttime = System.currentTimeMillis();
    BufferedWriter myWriter;
    try {
      myWriter = new BufferedWriter(new FileWriter(filename));
      myWriter.write(outString);
      myWriter.close();
    } catch (FileNotFoundException e) {
      // TODO 自动生成的 catch 块
      System.err.println(e.toString());
    } catch (IOException e) {
      // TODO 自动生成的 catch 块
      System.err.println(e.toString());
    }
    long endtime = System.currentTimeMillis();
    System.out.println("Reader/Writer策略写文件花费了:" + (endtime - starttime) + "ms");
  }
}

定义好一个算法接口和三个具体的策略类以后我们的策略模式就实现好了。在调用策略时我们只需要更改new的具体对象就行,如下:

Strategyforio iostrategy = new WriterandReader();
Strategyforio iostrategy = new Channel();
Strategyforio iostrategy = new Stream();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值