明确是王道

    ——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. Android编码规范

    Android-Code-Style 1.约定 Activity.onCreate(),Fragment.onActivityCreated(),紧跟成员变量后,方法内部保持简单,尽量只调用initX ...

  2. XML配置文件的命名空间与Spring配置文件中的头

    一直以来,写Spring配置文件,都是把其他配置文件的头拷贝过来,最多改改版本号,也不清楚哪些是需要的,到底是干嘛的.今天整理一下,拒绝再无脑copy. 一.Spring配置文件常见的配置头 < ...

  3. Node.js服务端框架谁才是你的真爱

    1. Express 背景: Express, 疯一般快速(而简洁)的服务端JavaScript Web开发框架,基于Node.js和V8 JavaScript引擎. Express 是一个基于 No ...

  4. QT Creator 快速入门教程 读书笔记(三)

    一   信号和槽 GUI 程序除了要绘制控件,还要响应系统和用户事件,例如重绘.绘制完成.点击鼠标.敲击键盘等.当事件发生时,UI 会产生相应的变化,让用户直观地看到. 大部分编程(例如Win SDK ...

  5. smokeping安装部署最佳实践

    1.1安装smokeping [root@linux-node2 ~]# cat /etc/redhat-release              #查看服务器信息 CentOS release 6. ...

  6. Nagios邮件报警

    p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; line-height: 150%; fon ...

  7. Myeclipse8.5开发-程序发布

    1.新建focus.xml文件.   2.添加如下内容   <Context path="/focus" docBase="F:\Workspaces\MyEcli ...

  8. yii2-验证规则,rules,判断条件

    yii2模型的验证规则,简单的使用我就不详细说了,想看的可以去看官网教程http://www.yiichina.com/doc/guide/2.0/structure-models#validatio ...

  9. python executemany的使用

    使用executemany对数据进行批量插入的话,要注意一下事项: #coding:utf8 conn = MySQLdb.connect(host = "localhost", ...

  10. 20144306《网络对抗》CAL_MSF基础运用

    1  实验内容 一个主动攻击,如ms08_067 一个针对浏览器的攻击,如ms11_050 一个针对客户端的攻击,如Adobe 成功应用任何一个辅助模块 2  实验过程记录 2.1 主动攻击MS08- ...