明确是王道

    ——Clean Code

类图:

先定义策略类

 package cn.no2.strategy;

 public abstract class Strategy {

     //省略属性
//算法方法
public abstract void algrithmInterface();
}

在定义若干策略子类

 package cn.no2.strategy;

 public class ConcreteStrategyA extends Strategy {

     @Override
public void algrithmInterface() {
// TODO Auto-generated method stub
System.out.println("算法A实现");
} }
public class ConcreteStrategyB extends Strategy { @Override
public void algrithmInterface() {
// TODO Auto-generated method stub
System.out.println("算法B实现");
} }
public class ConcreteStrategyC extends Strategy { @Override
public void algrithmInterface() {
// TODO Auto-generated method stub
System.out.println("算法C实现");
} }

最后定义业务逻辑"上下文类"

 package cn.no2.strategy;

 public class BizContext {

     Strategy strategy = null;

     public BizContext(String type) {

         switch (type) {
case "策略A":
strategy= new ConcreteStrategyA();
break;
case "策略B":
strategy= new ConcreteStrategyB();
break;
case "策略C":
strategy= new ConcreteStrategyC();
break;
}
} public void ContextInterface(){
strategy.algrithmInterface();
}
}

测试类

 package cn.no2.strategy;

 public class _Text {

     public static void main(String[] args) {
BizContext biz;
biz = new BizContext("策略A");
biz.ContextInterface();
biz = new BizContext("策略B");
biz.ContextInterface();
biz = new BizContext("策略C");
biz.ContextInterface();
}
}

诚然,上面的程序只是明确了框架,并没有任何实际的业务逻辑.下面来写个需求

输入单价、数量、计价方式,其中计价方式就是策略:

策略1:正常收费

策略2:打X折

策略3:满X元减Y元

输出结果。

上代码:

Strategy类:

 package cn.no2.strategy.instance;

 public abstract class Strategy {

     private double unitPrice;
private int count; public double getUnitPrice() {
return unitPrice;
} public void setUnitPrice(double unitPrice) {
this.unitPrice = unitPrice;
} public int getCount() {
return count;
} public void setCount(int count) {
this.count = count;
} //计算结果,返回double值
public abstract double algrithmInterface(); }

其子类:

 package cn.no2.strategy.instance;

 public class NomalStrategy extends Strategy {

     @Override
public double algrithmInterface() {
// 使用清晰规范的代码,定义变量,计算,返回
double result = ;
result = this.getUnitPrice()*this.getCount();
return result;
} }
public class DiscountStrategy extends Strategy { private double discount; public DiscountStrategy(double discount) {
super();
this.discount = discount;
} @Override
public double algrithmInterface() {
// 这里重写方法不能传入参数,所以需要定义该子类特有的属性,折扣
double result = ;
result = this.getUnitPrice()*this.getCount()*discount;
return result;
} }
public class FullReduceStrategy extends Strategy { double full;
double reduction; public FullReduceStrategy(double full, double reduction) {
super();
this.full = full;
this.reduction = reduction;
} @Override
public double algrithmInterface() {
// TODO Auto-generated method stub
double result = this.getUnitPrice()*this.getCount();
if (result >= full) {
result -= reduction;
}
return result;
} }

业务逻辑类:

 package cn.no2.strategy.instance;

 public class BizContext {

     private Strategy strategy = null;

     public BizContext(String type) {

         switch (type) {
case "正常收费":
strategy= new NomalStrategy();
break;
case "打8.5折":
strategy= new DiscountStrategy(8.5);
break;
case "满300减100":
strategy= new FullReduceStrategy(,);
break;
}
}
//彻底封装Strategy类
public void initStrategy(double unitPrice,int count) {
strategy.setUnitPrice(unitPrice);
strategy.setCount(count);
}
//这里实现的对strategy的封装,调用者只调用BizContext自己的方法
public double ContextInterface(){
return strategy.algrithmInterface();
}
}

Test类:

 package cn.no2.strategy.instance;

 import java.util.Scanner;

 public class _Text {

     public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入单价:");
double unitPrice = sc.nextDouble();
System.out.println("请输入数量:");
int count = sc.nextInt();
System.out.println("请输入策略:(正常收费,打8.5折,满300减100)");//这里如果改动,只需增加BizContext的业务逻辑
String strategy = sc.next();
BizContext biz = new BizContext(strategy);
biz.initStrategy(unitPrice,count);
double result = biz.ContextInterface();
System.out.println("总价是:"+result);
sc.close();
}
}

以上是策略模式的实际应用

策略模式与简单工厂对比:

简单工厂模式:客户端传一个条件进工厂类,工厂类根据条件创建相应的产品类对象,客户端使用该产品类对象.工厂类依赖产品类

策略模式:客户端创建一个Context类对象,并通过传入参数使用该对象。Context类中聚合了产品类,没有依赖关系

 

Java学习笔记——设计模式之二.策略模式的更多相关文章

  1. Java学习笔记——设计模式之九.建造者模式

     建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Product类: package cn.happy.design_pattern._09b ...

  2. Java进阶篇设计模式之十一 ---- 策略模式和模板方法模式

    前言 在上一篇中我们学习了行为型模式的访问者模式(Visitor Pattern)和中介者模式(Mediator Pattern).本篇则来学习下行为型模式的两个模式,策略模式(Strategy Pa ...

  3. Java进阶篇设计模式之二 ----- 工厂模式

    前言 在上一篇中我们学习了单例模式,介绍了单例模式创建的几种方法以及最优的方法.本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式.工厂方法和抽象工厂模式. 简单工厂模式 简单工厂模式是属于创建型模 ...

  4. JAVA中的设计模式三(策略模式)

    问题: 如何让算法和对象分开来,使得算法可以独立于使用它的客户而变化?   方案: 把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就 ...

  5. 设计模式C++学习笔记之一(Strategy策略模式)

    无意中,从网上下到一本电子书<24种设计模式介绍与6大设计原则>,很好奇这里有24种设计模式,印象中GOF写的<设计模式>(Design Patterns),好像只有23种吧. ...

  6. Java学习笔记——设计模式之八.外观模式

    外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 子系统: package cn.happy.design_patter ...

  7. Java学习笔记——设计模式之四.代理模式

    To be, or not to be: that is the question. --<哈姆雷特> 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. 上代码: p ...

  8. Java学习笔记——设计模式之七.模板方法模式

    模板方法模式(TemplateMethod),定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 结构图: 代码: 算法骨架 ...

  9. Java学习笔记——设计模式之六.原型模式(浅克隆和深克隆)

    That there's some good in this world, Mr. Frodo. And it's worth fighting for. 原型模式(prototype),用原型实例指 ...

随机推荐

  1. ajax 原理----初级篇

    一.贴dome,ajax三大步 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  2. 更换gitlab公网IP,引发的故障。

    gitlab更换公网IP地址,导致gitlab非常的很卡,并且ssh方式添加的远程仓库是无法git pull 或者git push,只有是添加http方式的可以正常git pull和git push ...

  3. 填坑实录 Android Studio 利用 ADB WIFI 插件实现真机无线调试

    总是用模拟器,小破本的渣内存无法承受,同时模拟器的版本大多停在4.4,无法体现Android 5.0.6.0 的版本特性,因此决定利用 Android Studio 的插件实现真机无线调试. 步骤如下 ...

  4. .Net EF框架的增删改查

    创建上下文对象: WordBoradEntities db = new WordBoradEntities(); 添加: //1.1创建实体对象 User uObj = new User() { uN ...

  5. css3 loading动画 三个省略号

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. VS2015下OpenGL库的配置

    写在前面: 最近要用到OpenGL,光是在VS2015下配置就费了很大的劲,现在将我的成果直接贡献给大家,希望能为需要在VS2015下配置OpenGL的读者省去一些麻烦. 正文: 资源地址1:http ...

  7. Linux - 进程间通信 - 信号量

    一.概念 简单来讲,信号量是一个用来描述临界资源的资源个数的计数器. 信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件.外部设备等)来实现进程间通信, 他本身 ...

  8. 兼容IE6/7/8/9的css3插件

    <!DOCTYPE html><html><head>    <meta charset="UTF-8" />    <tit ...

  9. iOS·UIKit & Foundation框架—Annotations & Category注解工具类

  10. 分布式文件系统:HDFS

    学习Hadoop,两个东西肯定是绕不过,MapReduce和HDFS,上一篇博客介绍了MapReduce的处理流程,这一篇博客就来学习一下HDFS. HDFS是一个分布式的文件系统,就是将多台机器的存 ...