策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

本文地址:http://www.cnblogs.com/wuyudong/p/5924223.html,转载请注明源地址。

策略模式的结构

  策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。下面就以一个示意性的实现讲解策略模式实例的结构。

这个模式涉及到三个角色:

  ● 环境(Context)角色:持有一个Strategy的引用。

  ● 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

  ● 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

策略模式的使用场景:

1)针对同一种问题的多种处理方式、仅仅是因为具体行为有差别时,

2)需要安全的封装多种同一类型的操作时

3)出现同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择具体子类时。

策略模式的实现

举个例子,计算公交车和地铁运行指定路程后所需的票价

package com.wuyudong.strategy.normal;

public class PriceCalculator {
// 公交车类型
private static final int BUS = 1;
// 地铁类型
private static final int SUBWAY = 2; public static void main(String[] args) {
PriceCalculator calculator = new PriceCalculator();
System.out.println("坐10公里的公交车的票价为:"
+ calculator.calculatePrice(10, BUS));
System.out.println("坐10公里的地铁的票价为:"
+ calculator.calculatePrice(10, SUBWAY)); } //计算公交价格
private int busPrice(int km) {
int extraTotal = km - 10;
int extraFactor = extraTotal / 5;
int fraction = extraTotal % 5;
int price = 1 + extraFactor * 1;
return fraction > 0 ? ++price : price;
} //计算地铁价格
private int subwayPrice(int km) {
if (km <= 6) {
return 3;
} else if (km > 6 && km < 12) {
return 4;
} else if (km < 22 && km > 12) {
return 5;
} else if (km < 32 && km > 22) {
return 6;
}
return 7;
} //根据类型来计算相应的价格
private int calculatePrice(int km, int type) {
if (type == BUS) {
return busPrice(km);
} else {
return subwayPrice(km);
}
}
}

如果再添加一种出租车的价格计算,添加相应的代码:

public class PriceCalculator {
// 公交车类型
private static final int BUS = 1;
// 地铁类型
private static final int SUBWAY = 2; // 出租车类型
private static final int TAXI = 3; public static void main(String[] args) {
PriceCalculator calculator = new PriceCalculator();
System.out.println("坐10公里的公交车的票价为:"
+ calculator.calculatePrice(10, BUS));
System.out.println("坐10公里的地铁的票价为:"
+ calculator.calculatePrice(10, SUBWAY)); } // 计算出租车价格
private int taxiprice(int km) {
return km * 2;
} // 根据类型来计算相应的价格
private int calculatePrice(int km, int type) {
if (type == BUS) {
return busPrice(km);
} else if (type == SUBWAY) {
return subwayPrice(km);
} else {
return taxiprice(km);
}
}
}

可见上面的代码耦合性较高,每当增加新的交通工具类型的时候,需要不断的修改大量的代码,这里使用策略模式重构:

首先定义一个抽象的价格计算接口:

//计算接口
public interface CalculateStrategy {
int calculatePrice(int km);
}

每一种出行方式都定义一个独立的计算策略类:

公交车计算策略

public class BusStrategy implements CalculateStrategy {
public int calculatePrice(int km) {
int extraTotal = km - 10;
int extraFactor = extraTotal / 5;
int fraction = extraTotal % 5;
int price = 1 + extraFactor * 1;
return fraction > 0 ? ++price : price;
} }

地铁计算策略

public class SubwayStrategy implements CalculateStrategy {

    public int calculatePrice(int km) {
if (km <= 6) {
return 3;
} else if (km > 6 && km < 12) {
return 4;
} else if (km < 22 && km > 12) {
return 5;
} else if (km < 32 && km > 22) {
return 6;
}
return 7;
}
}

再创建一个扮演Context的角色,代码如下:

public class TranficCalculator {
CalculateStrategy mStrategy; public static void main(String[] args) {
TranficCalculator calculator = new TranficCalculator();
//设置计算策略
calculator.setStrategy(new BusStrategy());
//计算价格
System.out.println("公交车乘10公里的价格:" + calculator.calculatePrice(10)); } public void setStrategy(CalculateStrategy mStrategy) {
this.mStrategy = mStrategy;
}
public int calculatePrice(int km) {
return mStrategy.calculatePrice(km);
}
}

这样即使需要添加出租车的价格计算,只需要简单的新建一个类,让其继承自CalculateStrategy接口并实现其中的方法即可

优点

1)结构清晰明了、使用简单直观

2)耦合度相对较低,扩展方便

3)操作封装因为更为测地、数据更为安全

缺点

子类增多

java设计模式--策略模式的更多相关文章

  1. java设计模式 策略模式Strategy

    本章讲述java设计模式中,策略模式相关的知识点. 1.策略模式定义 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户.策略模式属于对象的 ...

  2. JAVA 设计模式 策略模式

    用途 Title 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 策略模式是一种行为型模式. 结构

  3. 我的Java设计模式-策略模式

    今天给大家说说田忌赛马的故事.如有雷同,纯属巧合!话说在战国时期,群雄割据,硝烟四起,茶余饭后还是少不了娱乐活动的,其中赛马是最火爆的.一天,孙膑看到田忌像个死鸡似的就知道肯定赛马又输给了齐威王,立马 ...

  4. Java设计模式-策略模式详解

    前言 在软件领域中,设计模式作为一种经典的开发实践常常需要我们去深入的理解,而策略模式作为设计模式的一种,使用频率也是相对来说比较高的,在Java中,当我们学习TreeSet集合的时候,就采用了经典的 ...

  5. Java设计模式—策略模式

    1.策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(PolicyPattern). 定义如下:     Define a family of algorithms,e ...

  6. Java 设计模式--策略模式,枚举+工厂方法实现

    如果项目中的一个页面跳转功能存在10个以上的if else判断,想要做一下整改 一.什么是策略模式 策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理,最终可以实现解决 ...

  7. Java设计模式-策略模式(strategy)

    策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户.需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无 ...

  8. Java设计模式——策略模式

    策略模式的定义: 策略模式其实特别好理解,俗话说得好,条条大路通罗马,做的都是一件事,实现的方式却可以千万种,在这种情况下,如何使得每个人都可以根据自己的喜好来选择具体的方式,在调用时可以根据不同方式 ...

  9. Java设计模式-策略模式实际应用场景

    容错恢复机制        容错恢复机制是应用程序开发中非常常见的功能.那么什么是容错恢复呢?简单点说就是:程序运行的时候,正常情况下应该按照某种方式来做,如果按照某种方式来做发生错误的话,系统并不会 ...

随机推荐

  1. 【开源】OSharp框架解说系列(3):扩展方法

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  2. Android音频开发之AudioTrack实时播放

    前言: 其实在Android中录音可以用MediaRecord录音,操作比较简单.但是不能对音频进行处理.考虑到项目中做的是实时语音只能选择AudioRecord进行录音.然后实时播放也只能采用Aud ...

  3. 使用Python和Perl绘制北京跑步地图

    当你在一个城市,穿越大街小巷,跑步跑了几千公里之后,一个显而易见的想法是,如果能把在这个城市的所有路线全部画出来,会是怎样的景象呢? 文章代码比较多,为了不吊人胃口,先看看最终效果,上到北七家,下到南 ...

  4. CSS3 media queries + jQuery实现响应式导航

    目的: 实现一个响应式导航,当屏幕宽度大于700px时,效果如下: 当屏幕宽度小于700px时,导航变成一个小按钮,点击之后有一个菜单慢慢拉下来: 思路: 1.为了之后在菜单上绑定事件,并且不向DOM ...

  5. Spring Scope:Web项目中如何安全使用有状态的Bean对象?

    Web系统是最常见的Java应用系统之一,现在流行的Web项目多使用ssm或ssh框架,使用spring进行bean的管理,这为我们编写web项目带来了很多方便,通常,我们的controler层使用注 ...

  6. C语言分割字符串

    最近在做一道C语言题目的时候需要用到分割字符串,本来想自己手写的,也不会很麻烦,但想到其他语言都有分割字符串的库函数,C语言怎么会没有呢?所以,在网上搜了一搜,果然有这样的函数,还是很好用的,在此总结 ...

  7. ADO.NET数据访问技术

    ADO.NET数据访问技术 就是将C#和MSSQLl连接起来的纽带 可以通过ADO.NET将内存中的临时数据写入到数据库中,也可以将数据库中的数据提取到内存中供程序调用.是所有数据访问技术的基础. A ...

  8. 委托 lambda表达式浅显理解

    方法不能跟变量一样当参数传递,怎么办,C#定义了委托,就可以把方法当变量一样传递了,为了简单,匿名方法传递,省得再声明方法了:再简单,lambda表达式传递,比匿名方法更直观. public dele ...

  9. Devexpress TextAnnotation

    private void BindData() { chartControl1.AnnotationRepository.Clear(); chartControl1.Series.Clear(); ...

  10. 适配器模式 - Adapter

    Adapter Pattern, 适用场景: 接口匹配兼容: 客户代码统一调用同一接口: 在.NET中,DataAdapter用作DataSet和数据源之间的适配器以保存和检索数据. 参考: