java设计模式(2)策略模式

策略模式

  策略模式也是常用的设计模式之一,属于对象的行为模式。其定义为:针对一组算法,将算法封装到具有共同接口的独立类中,从而使它们可以互换。此模式让算法的变化独立于使用算法的客户。
   举个例子,超市要打折促销一批苹果。有半价折扣,有满减折扣,有88折有66折等等不同形式的促销方案,该超市可能这周用半价的方案,下周生意好了可能用88折,过些时也可能用满减。并且今后也可能添加更多方案。这时如何设计出可复用、可扩充、可维护的一组类来表达这种情景呢?
   根据策略模式的定义,我们可以把这些打折方法看做一组策略(或算法),将这些算法抽象到一个有打折方法的接口中。每个打折方法都是一个实现了此打折方法的类。代码如下:

/**
  * 算法的抽象接口
  */
public interface Strategy{
  //打折方法
  double disCount(int price);
}

/**
*方法A :8折
*/
public class StrategyA implements Strategy{
  @Override
  public double disCount(int price){
    return price*0.8;
  } 
}
/**
*方法B :满100后,多出部分半价
*/
public class StrategyB implements Strategy{
  @Override
  public double disCount(int price){
    return price<100?price:(price-100)*0.5+100;
  } 
}
/**
*方法C :优惠50
*/
public class StrategyC implements Strategy{
  @Override
  public double disCount(int price){
    return price-50;
  } 
}

  以上代码将每种打折促销方法都写成一个类,并拥有统一的父接口。所有实现了策略接口的类在该模式下都称为“具体策略类“,该接口为“抽象策略类”。目标是要实现苹果的不同折扣方案,苹果类又称为“环境角色类“。

public class Apple{  //模拟苹果,在策略模式中此类为“环境角色类”
    public Apple(){}
    public Apple(Strategy strategy){
      this.strategy=strategy; //通过构造函数给策略实例赋值
    }
    private double price; //价格
    private Strategy strategy; //保存该策略接口引用
    public void setPrice(double price){
      this.price=price;   
    }
    public double getPrice(){
      return price;
    }
    public double calculatePrice(){
        return strategy.disCount(price);
    }
}

public class Test{
   public static void main(String []args){
     Strategy strategy = new StrategyA(); //在这里更换具体策略
   //Strategy strategy = new StrategyB();
   //Strategy strategy = new StrategyC(); 
     Apple apple = new Apple(strategy);
     apple.setPrice(200);
     int discount = apple.calculatePrice();
     System.out.println("折扣后价格:"+discount);
   }
}

  在环境角色类中嵌入抽象的策略接口,以便在应用中动态改变所需的打折策略。上面例子中嵌入方式为:在环境角色类中保存一个抽象策略类的变量,在构造函数中为其赋值,当然,也可以直接在折扣方法的参数列表中拥有一个嵌入抽象策略类引用,等到调用该方法时再赋值。如下:

  public class Apple{

    private double price; //价格

    public void setPrice(double price){
      this.price=price;   
    }
    public double getPrice(){
      return price;
    }
    public double calculatePrice(){
        return price;
    }
    public double calculatePrice(Strategy strategy){
        return strategy.disCount(price);
    } 
  }
public class Test{
   public static void main(String []args){

     Apple apple = new Apple();
     apple.setPrice(200);
     int discount = apple.calculatePrice(new StrategyA());//在这里更换折扣策略
     System.out.println("折扣后价格:"+discount);
   }
}

  本人更倾向于使用第二种方式实现策略模式,因其耦合性更低,不用嵌入策略类的变量,不用在构造函数中耦合策略类。在Java API中,关于File类的list()方法(返回该File类底下的文件名或目录名的集组成的数组)即使用了策略模式。list方法有2个版本,如下:

public String[] list(); //没有参数,返回该目录下所有文件名组成的String数组

public String[] list(FilenameFilter filter); //有一个过滤器的参数,FilenameFilter 是一个接口

  带参数的list方法返回经过滤器筛选后的数组,FilenameFilter 相当于策略模式中的抽象策略,该接口含有一个选择文件名的方法定义,任何一个实现此接口的类充当此参数,实现自己的过滤效果。FilenameFilter 接口如下:

public interface FilenameFilter {
    boolean accept(File dir, String name);
}

实现具体的过滤策略

public static void main(String[]args){
  File file = new File(".");//将当前目录赋值给file
  //String []list = file.list(filter); filter应当是一个实现了FilenameFilter 接口的类的实例,这里使用匿名内部类实现,如下
   String[] list = path.list(new FilenameFilter() {
           //筛选文件名含有“Hello”的java文件
            public boolean accept(File f, String name) {
                return Pattern.matches("\S*Hello\S*\.java",name);
            }
        });
}

关于java的策略模式就讲到这里了,若有不正确的地方还请各位网友指正,联系方式:wthfeng@126.com。

参考文章:
1. 《Head First 设计模式》
2. http://www.cnblogs.com/java-my-life/archive/2012/05/10/2491891.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
策略模式(Strategy Pattern)是Java设计模式中的一种行为型模式,它定义了一系列的算法,并将每个算法封装在独立的类中,使得它们可以互相替换。这样可以使得算法的变化独立于使用它们的客户端。 在策略模式中,有三个主要角色: 1. 环境类(Context):持有一个策略类的引用,用于调用具体的策略。 2. 抽象策略类(Strategy):定义了一个公共接口或抽象类,用于具体策略类的统一调用。 3. 具体策略类(Concrete Strategy):实现了抽象策略类定义的接口或抽象类,提供具体的算法实现。 使用策略模式可以实现算法的动态切换,增加新的算法也不会影响到已有的代码。例如,假设我们需要实现一个排序算法,可以定义一个抽象策略类 SortStrategy,然后具体的排序算法(如快速排序、归并排序等)分别实现 SortStrategy,并在环境类中持有 SortStrategy 的引用。这样,通过更换不同的 SortStrategy 对象,就可以在运行时选择不同的排序算法。 策略模式能够有效地解耦策略的定义和使用,提高代码的灵活性和可维护性。同时,它也符合面向对象设计原则中的"开闭原则"(对扩展开放,对修改关闭)和"单一职责原则"(一个类应该只有一个引起变化的原因)。 希望这个简要的介绍能够帮助到你对策略模式的理解。如果还有其他问题,可以继续提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值