23中设计模式——策略模式

策略模式

一、基本概念

定义:什么是策略模式?个人认为,策略模式就是对一种行为有不同的“动作”,根据用户的需求进行选择不同的“动作”。 ps:个人认为有点类似于多态。

例子:在商城的购物过程中,针对不同用户有着不同的折扣。譬如,普通用户原价,白银用户9折,黄金用户8折。针对不同的用户有着不同的折扣,这样就可以使用到策略模式。

二、实例运用

商场收银系统,根据商品的单价和数量算出总价格。但是遇到商场不同的活动,有时候会全场打折9折,8折。有时候会是满减活动,譬如全场满200减50之类的。

package com.golf.strategy;

/**
* 创建抽象类---策略模式
*/
abstract class Strategy {

  public abstract double useAlgorithm(double money);
}

 

创建相应的具体算法实现,继承Strategy。通过构造方法,将需要的值写入。

打折收费:

package com.golf.strategy;

//打折收费
public class CashDiscount extends Strategy {
    private double discount;


  //每个具体的策略类的参数 都是自身特有的参数
  public CashDiscount(double discount){
      this.discount = discount;
  }

  @Override
  public double useAlgorithm(double money) {
      return money * discount;
  }
}

正常收费:

package com.golf.strategy;

//正常收费
public class CashNomarl extends Strategy {

  @Override
  public double useAlgorithm(double money) {

      return money;
  }


}

折返收费:

package com.golf.strategy;

//满减收费 譬如满200-50
public class CashReturn extends Strategy{
  private double condition;
  private double returnMoney;
  public CashReturn(double condition,double returnMoney){ //构造函数是每个具体的策略类的特有的参数
      this.condition = condition;
      this.returnMoney = returnMoney;
  }
  @Override
  public double useAlgorithm(double money) { //重写抽象的策略类的参数都是共同的
      return money-Math.floor(money/condition)*returnMoney;
  }
}

上下文环境类----有点类似于简单工厂模式里面的工厂

package com.golf.strategy;

public class StrategyContext {
  private Strategy strategy;   //创建定义的抽象父类(接口)

  public StrategyContext(Strategy strategy){ //通过构造函数进行
      this.strategy = strategy;
  }

  public double exc(double money){
      double result = strategy.useAlgorithm(money);
      return result;
  }

}

客户端:

package com.golf.strategy;

import java.util.Scanner;

//客户端的实现
public class Client {

  public static void main(String[] args) {
      Scanner input=new Scanner(System.in);
      System.out.println("请输入单价:");
      String singlePrice = input.next();
      System.out.println("请输入商品数量:");
      String num = input.next();
      double money = Double.parseDouble(singlePrice)*Double.parseDouble(num); //总价

      //根据自己所需要的算法 创建相应的对象
      StrategyContext strategyContext = new StrategyContext(new CashDiscount(0.8));
      double exc = strategyContext.exc(money);
      System.out.println("总价为:"+exc);
  }
}

其实可以将创建具体的那种策略放到Strategy类中,将简单工厂模式和策略类结合一下

上下文环境的StrategyContext

将策略模式和简单工厂模式结合之后,client避免直接去创建需要的对象,而是通过上下文环境类去创建。这样client只需要消费就行,减少了耦合度。

package com.golf.strategy;

public class StrategyContext2 {
  private Strategy strategy;

  public StrategyContext2(String type){
      switch (type){
          case "普通消费":
              this.strategy = new CashNomarl();
              break;
          case "打折消费":
              this.strategy = new CashDiscount(0.8);
              break;
          case "满减活动":
              this.strategy = new CashReturn(200,100);
      }
  }

  public double exc(double money){
      double result = strategy.useAlgorithm(money);
      return result;
  }


}

客户端:

package com.golf.strategy;

import java.util.Scanner;

//将策略模式和简单工厂模式进行结合
public class Client2 {

  public static void main(String[] args) {
      Scanner input=new Scanner(System.in);
      System.out.println("请输入单价:");
      String singlePrice = input.next();
      System.out.println("请输入商品数量:");
      String num = input.next();
      double money = Double.parseDouble(singlePrice)*Double.parseDouble(num); //总价

      //根据自己所需要的算法 创建相应的对象
      StrategyContext2 strategyContext = new StrategyContext2("满减活动");

      double exc = strategyContext.exc(money);
      System.out.println("总价为:"+exc);
  }
}
三、策略模式的优缺点

优点:

1、算法可以自由的切换,根据用户的需求,使用不同的算法。

2、扩展性好,新增算法无需在原来代码上修改,直接新增就行。

缺点:

1、每一个策略都是一个类,当项目的复杂度上升的时候,策略过多,类变多,复杂性大大上升。

2、上层模块必须知道有哪些策略。(将工厂模式结合一下可以解决)

package com.golf.strategy;

import java.util.Scanner;

//将策略模式和简单工厂模式进行结合
public class Client2 {

public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请输入单价:");
String singlePrice = input.next();
System.out.println("请输入商品数量:");
String num = input.next();
double money = Double.parseDouble(singlePrice)*Double.parseDouble(num); //总价

//根据自己所需要的算法 创建相应的对象
StrategyContext2 strategyContext = new StrategyContext2("满减活动");

double exc = strategyContext.exc(money);
System.out.println("总价为:"+exc);
}
}
posted @ 2019-11-19 11:01  写程序不掉发  阅读(165)  评论(0)    收藏  举报