第二话-策略模式



写在前面:本人最近在看《大话设计模式》这本书,书里是用C#讲解的实例。现在写心得笔记与大家分享,就试着写一个JAVA版的。例子还是书里的例子。不过是Java语言实现的。后面也会给出本人的一些理解建议。谢谢《大话设计模式》的作者。

一、什么事策略模式?

策略模式,顾名思义就是对策略封装的一种模式。什么是策略,策略就是策略。在程序里就体现为程序的灵魂算法,不同的算法就是不同的策略。策略模式主要是针对算法的决策模式。上一篇的简单工厂模式主要是对对象分发的一种模式。

二、应用于什么情况?

多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为;

 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现;

对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
三、实例来袭(超市收银)。
超市是怎么收银的?扫你买的商品,系统根据商品的价格和数量进行计算总和,最后得出一共多少money。这是再简单不过的了,会有什么模式?有,当然有。假如超市庆十一,搞打折活动,收银系统会对产品进行打折计算;你可能想到是不是到双十一会不会有返利,是的,会有的。老是有这种活动是不是很头疼?系统要不同的改动。好烦。那咱们就可以用到我们伟大的设计模式,策略模式。
同样,既然是超市收银,它收的是商品的钱,咱们需要一个商品类Goods。一个主类用于交互Main类。策略模式,那咱们先定义一个总的策略抽象类Strategy,然后再定义一些策略实现类,本文只有两个策略,一个是折扣策略DiscountStrategy,一个是返利策略ReturnStrategy。然后还需要一个对策略配置的类,这个是本文的关键,但他没有什么代码,只是一个形式而已,Context上下文类。在Context类中,咱们需要先配置策略,然后提供用户调用策略接口。呵呵,是不是想到了什么?配置策略,其实就是对象的分发,那咱们就可以用到之前的工厂模式了。再加一个工厂类,StrategyFactory。
懂了么?看来是不懂了。那就继续。先不要晕,晕了也没事,再晕一会就会了。
代码驾到:
Main.java
public class Main {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  Goods[] goods = { new Goods("杯子", 9.9f, 1), new Goods("笔芯", 1f, 6),
    new Goods("书包", 199f, 1) };
  Context context1 = new Context("打折");
  context1.configure(goods);
  Context context2 = new Context("返送");
  context2.configure(goods);
 }
}


Goods.java
public class Goods {
 private String name;
 private float price;
 private int num;
 public Goods() {
 }
 public Goods(String name, float price, int num) {
  this.name = name;
  this.price = price;
  this.num = num;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public float getPrice() {
  return price;
 }
 public void setPrice(float price) {
  this.price = price;
 }
 public int getNum() {
  return num;
 }
 public void setNum(int num) {
  this.num = num;
 }
}

Strategy.java
public abstract class Strategy {
 /**
  * 放置策略的抽象类,本程序只有一个策略接口
  */
 public abstract void algorithm(Goods[] goods);
}

DiscountStrategy.java
public class DiscountStrategy extends Strategy {
 private float rate;
 public DiscountStrategy(float rate) {
  this.rate = rate;
 }
 public void algorithm(Goods[] goods) {
  // TODO Auto-generated method stub
  float total = 0;
  for (int i = 0; i < goods.length; i++) {
   float sum = goods[i].getPrice() * goods[i].getNum() * rate;
   total += sum;
   System.out.println("商品" + i + "-[" + goods[i].getName() + "]\t单价:"
     + goods[i].getPrice() + "\t数量:" + goods[i].getNum()
     + "\t折率" + rate + "\t共:" + sum);
  }
  System.out.println("总计:" + total);
 }
}


ReturnStratergy.java
public class ReturnStrategy extends Strategy {
 private float limit;// 满多少
 private float money;// 送多少
 public ReturnStrategy(float limit, float money) {
  this.limit = limit;
  this.money = money;
 }
 public void algorithm(Goods[] goods) {
  // TODO Auto-generated method stub
  float total = 0;
  for (int i = 0; i < goods.length; i++) {
   float sum = goods[i].getPrice() * goods[i].getNum();
   total += sum;
   System.out.println("商品" + i + "-[" + goods[i].getName() + "]\t单价:"
     + goods[i].getPrice() + "\t数量:" + goods[i].getNum()
     + "\t共:" + sum);
  }
  if (total >= limit) {
   total -= money;
   System.out.println("满" + limit + "送" + money);
  }
  System.out.println("总计:" + total);
 }
}

StrategyFactory.java
public class StrategyFactory {
 public static Strategy createStrategy(String string) {
  Strategy strategy = null;
  if ("打折".equals(string)) {
   strategy = new DiscountStrategy(0.8f);
  } else if ("返送".equals(string)) {
   strategy = new ReturnStrategy(200f, 50f);
  }
  return strategy;
 }
}

Context.java
public class Context {
 private Strategy strategy;
 public Context(String string) {
  this.strategy = StrategyFactory.createStrategy(string);
 }
 public void configure(Goods[] goods) {
  strategy.algorithm(goods);
 }
}
懂了么?还不懂?那就把代码咱贴上去运行一下你就明白了。
四、小结和建议
策略模式只是对策率的一种分配,看似和简单工厂模式很像,但他俩真的是没关系,请注意,简单工厂模式一般都是返回一个实例,而策略模式的Context类是对策略的配置和执行。其实有没有关系也没关系了,使用设计模式就是为了代码的“高内聚,低耦合”,为了代码“可复用”,“可扩展”,“易维护”,“灵活多变”而已。
对于本程序,只是对所有商品都进行了策略,实际上是针对不同的商品有不同的策略,此时应该怎么解决呢?我感觉,可以把策略放到商品里,因为策略是针对商品的,让每个商品都有一个策略的属性。这样可以实现
还有就是在各个策略里计算时,代码大同小异,那又该怎么优化呢?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柠檬李先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值