JAVA设计模式 之 策略模式
一. 定义
设计模式定义了算法族,分别封装起来,让他们之间可以互相替代,此模式让算法的变化独立于使用算法的客户(该定义来自于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设计模式 之 策略模式的更多相关文章
- Java设计模式1——策略模式(Strategy Pattern)
最近觅得一本好书<您的设计模式>,读完两章后就能断言,一定是一头极品屌丝写的,而且是专写给开发屌丝男的智慧枕边书,小女子就委屈一下,勉强看看,人笨,谁让他写得这么通俗易懂呢!为了加深理解, ...
- Java设计模式之策略模式(一)
今年寒假没有回家,打算利用这个假期的时间进行学习设计模式,这一个人感觉比较牛的知识,前一段时间一直在忙着搞自己的专业课,还有就是捣鼓了一下Linux系统,没有好好的学习关于Java还有Android方 ...
- Java设计模式---Strategy策略模式
参考于 : 大话设计模式 马士兵设计模式视频 1.场景介绍 购物网站上有一个产品,有三个字段,档次,价格,重量. 有些同学喜欢轻的,有些手头紧,想要便宜的,有些喜欢档次高的. 那么我们为了提高网站用户 ...
- 折腾Java设计模式之策略模式
博客原文地址 简介 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式.简单理解就是一组算法,可以互换,再简单点策略就是封装算法. ...
- Java 设计模式之 策略模式
思维导图: 我们先来看 STRATEGY 设计模式的通俗解释: 跟不同类型的MM约会,要用不同的策略,有的请电影比较好,有的则去吃小吃效果不错,有的去海边浪漫最合适,但目的都是为了得到 MM 的芳心, ...
- java设计模式之策略模式
策略模式 定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户(大话设计模式). 策略模式UML图 策略模式代码 古代的各种计谋都是一种策略,这次我们 ...
- Java设计模式之-----策略模式
首先,我们来看下策略模式的概念.一般的解释如下: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.(原文:The St ...
- java设计模式之——策略模式
1.策略模式有什么好处? 策略模式的好处在于你可以动态的改变对象的行为. 2.设计原则 设计原则是把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口(c++中可以用虚类),然后在类中包含这 ...
- 小白学习java设计模式之策略模式
策略模式:1.分析项目中的变化部分与不变部分(每个设计模式都要分析的)2.多用组合少用继承;用行为类组合,而不是行为继承,更具有弹性直接上代码: package com.wz.oneStrategis ...
随机推荐
- POJ3207Ikki's Story IV - Panda's Trick(模板题)
题目链接 题意:平面上,一个圆,圆的边上按顺时针放着n个点.现在要连m条边,比如a,b,那么a到b可以从圆的内部连接,也可以从圆的外部连接.给你的信息中,每个点最多只会连接的一条边.问能不能连接这m条 ...
- 十分钟入门less(翻译自:Learn lESS in 10 Minutes(or less))
十分钟入门less(翻译自:Learn lESS in 10 Minutes(or less)) 注:本文为翻译文章,因翻译水平有限,难免有缺漏不足之处,可查看原文. 我们知道写css代码是非常枯燥的 ...
- Saltstack之SSH(十一)
Saltstack之SSH 安装 yum install -y salt-ssh 官方文档 https://docs.saltstack.com/en/latest/topics/ssh/index ...
- BZOJ2208: [Jsoi2010]连通数
tarjan缩点后拓扑排序,每一个点用一个bitset记录哪些点能到达它. PS:数据太水,暴力能过. #include<bits/stdc++.h> using namespace st ...
- css012 css布局简介
css012 css布局简介 一. 网页布局的类型 网页布局的类型 1.固定宽度 2.流式 3.相应式web设计 二. 如何进行css布局 1.强大的<div>标签 网页的h ...
- Linux的95个小技巧
Linux的95个小技巧 by WEB全栈工程师 on 2012 年 03 月 27 日 这里总结了Linux使用中的一些小技巧 1.实现RedHat非正常关机的自动磁盘修复 先登录到服务器,然后在/ ...
- 使用ThreadLocal、Apache的dbutils的QueryRunner和dbcp2数据库连接池的BasicDataSource封装操作数据库工具
package hjp.smart4j.framework.helper; import hjp.smart4j.framework.util.CollectionUtil; import hjp.s ...
- Docker 修改默认存储位置
首先使用 docker info 查看 docker 的基本信息 sudo docker info Containers: 0 Images: 5 Storage Driver: devicemapp ...
- Java序列化的几种方式以及序列化的作用
Java序列化的几种方式以及序列化的作用 本文着重讲解一下Java序列化的相关内容. 如果对Java序列化感兴趣的同学可以研究一下. 一.Java序列化的作用 有的时候我们想要把一个Java对象 ...
- QT笔记
1.菜单栏上的弹出窗口 void MainWindow::on_new_action_triggered() { MyDialog myDialog;//MyDialog是一个ui m ...