一. 定义

设计模式定义了算法族,分别封装起来,让他们之间可以互相替代,此模式让算法的变化独立于使用算法的客户(该定义来自于Head First 设计模式)。

二. 应用场景

当我们在应用程序中完成一项功能时,有些需要经常变化的算法我们需要就独立的抽取出来,将使用抽象的引用为在具体的功能类中标示,并且在程序运行时能够动态的改变这些算法功能。

三. 设计原则

  设计模式告诉我们:

(1). 找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。

(2). 要针对接口编程,而不是针对实现的编程。

(3). 多用组合,少用继承。

四. 举例说明

假如某超级市场有这样的会员打折行为,会员分为三个等级,这里就用A,B,C来替代,会员A具有一种算法,会员B具有一种算法,会员C也具有一种算法。因为以后可能有更多的会员计算方法或者按不同节日为会员打折等,使用JAVA我们一般的做法是创建一个类,在类中判断如果是会员A我们就按照一种计算方法结账,如果是会员B我们就会用另外以一种方法结账,如果是会员C我们在用一种结账算法,这样呢这个类中就多了很多if ... else 判断,并且这个方法相当的长,问题就暴露出来了,日后你可能不愿意维护这样的代码,但是有的人说了,我把不同的算法都提出来为一个方法不行行了吗?恩,很对,那么在if...else里面就可以减少代码量了,可是如果超级市场有新增加了新的会员,或者会员算法需要修改的时候,问题是不是又来了,所以为了使日后维护方便,做到最少的修改,即满足开闭原则,这里使用策略模式来解决该问题。

策略模式解决该问题的思路是将具体的不同的会员算法提出来作为一个类,然后呢实现一个统一的接口,这样在日后增加了一个会员算法,只需要添加一种实现而已,然后在超市的这个类中持有这个会员算法的接口引用即可。

封装行为类图:


具体看如下代码:

1. 会员结账接口 ISettleAccounts.java

/**
* 会员结账接口
* @author Administrator
*/ public interface ISettleAccounts { /**
* 计算账目
* @return
*/
public double calculate(double reallyPrice);
}

2. 会员A打折算法 MemberA.java 继承统一的会员结账接口

public class MemberA implements ISettleAccounts {

	public double calculate(double reallyPrice) {

		System.out.println("MemberA 的账目计算方法[9折计算].....");

		return reallyPrice * 90/100;
} }

3. 会员B打折算法 MemberB.java 继承统一的会员结账接口

public class MemberB implements ISettleAccounts {

	public double calculate(double reallyPrice) {

		System.out.println("MemberB 的账目计算方法[8.5折计算].....");

		return reallyPrice * 85/100;
} }

3. 会员C打折算法 MemberC.java 继承统一的会员结账接口

public class MemberC implements ISettleAccounts {

	public double calculate(double reallyPrice) {

		System.out.println("MemberA 的账目计算方法[8折计算].....");

		return reallyPrice * 80/100;
} }

4. 超级市场类Supermarket.java 

/**
* 超级市场
* @author Administrator
*/ public abstract class Supermarket { // 持有结账引用
private ISettleAccounts settleAccounts; // 其它的属性
// private ...... // 可以设置某一种会员打折类别,也就是在运行的时候可以改变某种会员计算方法
public void setSettleAccounts(ISettleAccounts settleAccounts) {
this.settleAccounts = settleAccounts;
} /**
* 打折计算
* @param reallyPrice
* @return
*/
public double discount(double reallyPrice){
return settleAccounts.calculate(reallyPrice);
} // 其它的方法
// public ...... }

5. 顾客会员A CustomerMemberA.java 类

在这个顾客类中只需要将会员A的算法动态的设置其中即可。当然你还可以创建顾客会员B,顾客会员C。。。。

/**
* 客户会员A
* @author Administrator
*/ public class CustomerMemberA extends Supermarket { // 构造客户会员A
public CustomerMemberA(){
super.setSettleAccounts(new MemberA());
} }

6. 测试类 CustomerMemberATest.java 

/**
* 会员A来超级市场购物结账,并且实际消费是1200元
* @author Administrator
*/ public class CustomerMemberATest extends Supermarket { public static void main(String[] args) { // 创建客户会员A
CustomerMemberA customerMemberA = new CustomerMemberA();
System.out.println(customerMemberA.discount(1200)); } }

7. 运行测试结构

MemberA 的账目计算方法[9折计算].....
1080.0

JAVA设计模式 之 策略模式的更多相关文章

  1. Java设计模式1——策略模式(Strategy Pattern)

    最近觅得一本好书<您的设计模式>,读完两章后就能断言,一定是一头极品屌丝写的,而且是专写给开发屌丝男的智慧枕边书,小女子就委屈一下,勉强看看,人笨,谁让他写得这么通俗易懂呢!为了加深理解, ...

  2. Java设计模式之策略模式(一)

    今年寒假没有回家,打算利用这个假期的时间进行学习设计模式,这一个人感觉比较牛的知识,前一段时间一直在忙着搞自己的专业课,还有就是捣鼓了一下Linux系统,没有好好的学习关于Java还有Android方 ...

  3. Java设计模式---Strategy策略模式

    参考于 : 大话设计模式 马士兵设计模式视频 1.场景介绍 购物网站上有一个产品,有三个字段,档次,价格,重量. 有些同学喜欢轻的,有些手头紧,想要便宜的,有些喜欢档次高的. 那么我们为了提高网站用户 ...

  4. 折腾Java设计模式之策略模式

    博客原文地址 简介 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式.简单理解就是一组算法,可以互换,再简单点策略就是封装算法. ...

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

    思维导图: 我们先来看 STRATEGY 设计模式的通俗解释: 跟不同类型的MM约会,要用不同的策略,有的请电影比较好,有的则去吃小吃效果不错,有的去海边浪漫最合适,但目的都是为了得到 MM 的芳心, ...

  6. java设计模式之策略模式

    策略模式 定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户(大话设计模式). 策略模式UML图   策略模式代码 古代的各种计谋都是一种策略,这次我们 ...

  7. Java设计模式之-----策略模式

    首先,我们来看下策略模式的概念.一般的解释如下:     策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.(原文:The St ...

  8. java设计模式之——策略模式

    1.策略模式有什么好处? 策略模式的好处在于你可以动态的改变对象的行为. 2.设计原则 设计原则是把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口(c++中可以用虚类),然后在类中包含这 ...

  9. 小白学习java设计模式之策略模式

    策略模式:1.分析项目中的变化部分与不变部分(每个设计模式都要分析的)2.多用组合少用继承;用行为类组合,而不是行为继承,更具有弹性直接上代码: package com.wz.oneStrategis ...

随机推荐

  1. CF570D:Tree Requests

    传送门 DFS重标号+二分 打比赛的时候想了很多方法..DFS序,BFS序,倍增什么的都考虑了一遍,但是几乎要么是可以维护两个区间但是代码复杂度爆炸,要么就是只能维护单一维度的信息. 这道题的具体做法 ...

  2. (转)Rest介绍

    参考文献:Rest简介 REST是一种组织Web服务的架构,其只在架构方面提出了一系列约束. 关于Restful的无状态 所以在stackoverflow中,我们常常会看到有人问:我现在使用了这样一种 ...

  3. Deep Learning in a Nutshell: History and Training

    Deep Learning in a Nutshell: History and Training This series of blog posts aims to provide an intui ...

  4. php生成excle

    方法一: 新建index.php,代码如下 <?php header("Content-type:application/vnd.ms-excel"); header(&qu ...

  5. Occlusion Culling

    遮挡剔除 http://www.bjbkws.com/online/1092/ unity遮挡剔除(应用) http://www.unitymanual.com/thread-37302-1-1.ht ...

  6. RHEL-界面中文乱码问题

    一.虚拟机里的rhel更换为中文简体后,中文字符变为小方块 二.解决方法: 安装中文支持的软件包 fonts-chinese-3.02-12.el5.noarch.rpm fonts-ISO8859- ...

  7. 解决并发情况下库存减为负数问题--update2016.04.24

    场景: 一个商品有库存,下单时先检查库存,如果>0,把库存-1然后下单,如果<=0,则不能下单,事务包含两条sql语句: ; update products ) WHERE id=; 在并 ...

  8. Yii2.0 GridView 新增添加按钮

    <?= GridView::widget([ 'dataProvider' => $dataProvider, 'filterModel' => $searchModel, 'col ...

  9. HDInsight 指定输出目录 insert overwrite

    基本语法 insert overwrite local directory '/example/demo/' select * from table; 可以格式化输出 insert overwrite ...

  10. Orchard源码分析(5.3):EndRequest事件处理(DefaultOrchardHost.EndRequest方法)

    EndRequest事件处理的作用是处理完"处理引擎(ProcessingEngine)"中的任务(Task).           void IOrchardHost .EndR ...