Java与设计模式-策略模式
在实际开发中,可能会遇到这样一个情况,某一功能的实现分为多种算法,这些算法能够认定为策略,在实际操作时选择不同算法或策略进行操作得出终于结果。在实际生活中。这些样例也是举不胜举。比如。商场举行活动,满100元减10元,满200元减30元,满500元减100元等等...这样每消费一笔,依据这一笔钱消费的多少。计算终于应支付的钱相应着不同的算法,这些相应的不同计算方法就能够认定为是不同的策略。
在某东购物时,依据不同的用户等级,打折力度也是不同的。
策略模式的UML类图參照下图:
假如没有策略模式。实现某东购物计算终于付款的方法如何呢?
package com.strategy.demo; public class NoStrategy {
/**
* 不使用測量模式实现
* @param args
*/
private static final int NOCARDUSER=1;
private static final int IRONCARDUSER=2;
private static final int GOLDCARDUSER=3; public static void main(String[] args) {
NoStrategy NoStrategy1=new NoStrategy();
NoStrategy NoStrategy2=new NoStrategy();
NoStrategy NoStrategy3=new NoStrategy(); System.out.println("没有卡牌的买家买100元货物终于应付款:"+NoStrategy1.getPrice(100.0, 1)); System.out.println("铁牌的买家买100元货物终于应付款:"+NoStrategy2.getPrice(100.0, 2)); System.out.println("金牌的买家买100元货物终于应付款:"+NoStrategy3.getPrice(100.0, 3)); } private double getNoCardPrice(double price){
return price;
} private double getIronCardPrice(double price){
return price*0.9;
} private double getGoldCardPrice(double price){
return price*0.7;
} private double getPrice(double price,int type){
if(type==NOCARDUSER){
return getNoCardPrice(price);
}else if(type ==IRONCARDUSER){
return getIronCardPrice(price);
}else if(type ==GOLDCARDUSER){
return getGoldCardPrice(price);
}else {
return 0;
}
} }
执行实例:
呀,得出正确的答案了,这时你是不是应该满足了呢。应该高枕无忧了呢?突然,主管说要添加钻石用户的类别,钻石用户打六折,这时你怎么实现呢?在里面在添加钻石用户的类型,再添加计算钻石用户的方法,再再最后的推断里添加i f else? 这种确能够实现功能,可是是不是不满足开闭原则呢?并且随着用户种类的不断添加,你的if else是不是也越来越长,逻辑也越来越复杂呢?导致系统扩展性和稳定性越来越差呢? 所以,这种方式在实际中显然实不可取的,以下我们看一下怎样使用策略模式来实现上面的需求。
1.PriceStrategyInterface 接口,相应UML类图中的Strategy接口:
package com.strategy.demo; public interface PriceStrategyInterface { double calPrice(double price);
}
2.实现类,无卡用户:
package com.strategy.demo; public class NoCardUserStrategy implements PriceStrategyInterface {
/**
* 无牌买家。原价
*/ @Override
public double calPrice(double price) {
return price;
} }
3.实现类。铁卡用户:
package com.strategy.demo; public class IronCardUserStrategy implements PriceStrategyInterface {
/*
* 铁牌买家
* (non-Javadoc)
* @see com.strategy.demo.PriceStrategyInterface#calPrice(double)
*/ @Override
public double calPrice(double price) {
return price*0.9;
} }
4.实现类。金卡用户:
package com.strategy.demo; public class GoldCardUserStrategy implements PriceStrategyInterface {
/**
* 金牌买家
*/ @Override
public double calPrice(double price) {
return price*0.7;
} }
5.环境对象。用来操作策略:
package com.strategy.demo; public class PriceContext {
/**
* 操作类
*/ PriceStrategyInterface priceStrategyInterface;
/*
* 通过初始化传入对象
*/
public PriceContext(PriceStrategyInterface priceStrategyInterface) {
this.priceStrategyInterface=priceStrategyInterface;
}
/*
* 通过对象计算返回值
*/
public double getPrice(double price){
return priceStrategyInterface.calPrice(price);
}
}
环境对象初始化时。将相应的策略对象传入,然后调用方法返回计算值。
6.构建測试类,測试:
package com.strategy.demo; public class TestClass { public static void main(String[] args) {
PriceContext priceContext=new PriceContext(new NoCardUserStrategy());
System.out.println("没有卡牌的买家买100元货物终于应付款:"+priceContext.getPrice(100.0)); PriceContext priceContext2=new PriceContext(new IronCardUserStrategy());
System.out.println("铁牌的买家买100元货物终于应付款:"+priceContext2.getPrice(100.0)); PriceContext priceContext3=new PriceContext(new GoldCardUserStrategy());
System.out.println("金牌的买家买100元货物终于应付款:"+priceContext3.getPrice(100.0)); } }
执行上面的实例:
得到了和第一个方法一样的正确答案,这时我们假如要添加一个钻石买家的种类。怎么实现呢?我们仅仅须要添加一个策略实现类:
package com.strategy.demo; public class DiamondUserStrategy implements PriceStrategyInterface { @Override
public double calPrice(double price) {
return price*0.6;
} }
然后測试类添加一条钻石类买家的购物:
package com.strategy.demo; public class TestClass { public static void main(String[] args) {
PriceContext priceContext=new PriceContext(new NoCardUserStrategy());
System.out.println("没有卡牌的买家买100元货物终于应付款:"+priceContext.getPrice(100.0)); PriceContext priceContext2=new PriceContext(new IronCardUserStrategy());
System.out.println("铁牌的买家买100元货物终于应付款:"+priceContext2.getPrice(100.0)); PriceContext priceContext3=new PriceContext(new GoldCardUserStrategy());
System.out.println("金牌的买家买100元货物终于应付款:"+priceContext3.getPrice(100.0)); PriceContext priceContext4=new PriceContext(new DiamondUserStrategy());
System.out.println("钻石卡的买家买100元货物终于应付款:"+priceContext4.getPrice(100.0)); } }
执行实例:
是不是扩展起来特别easy?条理也十分清晰。总结一下策略模式的长处:
1. 结构清晰,使用简单直观。
2. 系统耦合性减少。扩展方便;
3. 操作封装彻底。数据更为安全。(在TestClass中,仅仅知道相关实现类,并不涉及详细计算方法)
当然,策略方式也存在一定的缺点:
由图能够直观的看出,随着策略的不断添加。子类数量变得庞大。
喜欢的朋友关注我和我的微信平台
Java与设计模式-策略模式的更多相关文章
- 15. 星际争霸之php设计模式--策略模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型)
[.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它 ...
- linkin大话设计模式--策略模式
linkin大话设计模式--策略模式 Strategy [ˈstrætədʒi] 策略 策略模式用于封装系列的算法,这些算法通常被封装在一个称为Context的类中,客户端程序可以自由的选择任何一种 ...
- [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)
[.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...
- java设计模式 策略模式Strategy
本章讲述java设计模式中,策略模式相关的知识点. 1.策略模式定义 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户.策略模式属于对象的 ...
- JAVA 设计模式 策略模式
用途 Title 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 策略模式是一种行为型模式. 结构
- 我的Java设计模式-策略模式
今天给大家说说田忌赛马的故事.如有雷同,纯属巧合!话说在战国时期,群雄割据,硝烟四起,茶余饭后还是少不了娱乐活动的,其中赛马是最火爆的.一天,孙膑看到田忌像个死鸡似的就知道肯定赛马又输给了齐威王,立马 ...
- Java设计模式-策略模式详解
前言 在软件领域中,设计模式作为一种经典的开发实践常常需要我们去深入的理解,而策略模式作为设计模式的一种,使用频率也是相对来说比较高的,在Java中,当我们学习TreeSet集合的时候,就采用了经典的 ...
- Java设计模式—策略模式
1.策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(PolicyPattern). 定义如下: Define a family of algorithms,e ...
随机推荐
- 【STM32H7教程】第23章 STM32H7的MPU内存保护单元(重要)
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第23章 STM32H7的MPU内存保护单元 ...
- mybatis一对多关系的关联查询
问题描述:实现两张表的关联查询 学生表: 班级表: 要实现学生管理信息中有所在班级的名称,即如下图所示 1.对应学生表的pojo类写全班级表中的字段(适用于要连接的表字段较少的情况) sql语句直接在 ...
- BZOJ 4195 程序自动分析
4195: [Noi2015]程序自动分析 Description 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,-代表 ...
- Windows7下caffe-ssd-microsoft下编译
整个编译可谓漫长 编译了两天 网上教程也很多 但是也很杂 遇到各种错误 总归是编完了 1.下载Windows版本的Caffe-SSD源码 下载链接:https://github.com/conner9 ...
- Spring Boot (19) servlet、filter、listener
servlet.filter.listener,在spring boot中配置方式有两种:一种是以servlet3开始提供的注解方式,另一种是spring的注入方式. servlet注解方式 serv ...
- 【Oracle】append
我们在生产环境中经常遇到需要往表中插入大量数据的情况,怎么样才能让插入数据的速度变快呢?Oracle中的append简直就是神器!!没图说个**,直接上图: 是不是看晕了?哈哈,莫慌,请看下面总结: ...
- Spring MVC 中的基于注解的 Controller(转载)
终于来到了基于注解的 Spring MVC 了.之前我们所讲到的 handler,需要根据 url 并通过 HandlerMapping 来映射出相应的 handler 并调用相应的方法 ...
- Git 从github克隆文件至本地
学习阶段,同一个项目,如何保障家与公司的代码同步的问题,可以使用git克隆来解决 在家将项目提交到了GitHub上,现在来到公司,需要将GitHub上的项目克隆到本地,那么对于公司的电脑来说,同样需要 ...
- TCP协议的三次握手、四次挥手
TCP三次握手 TCP的连接的建立需要发送三个包,一次称为三次握手(Three-way Handshake). 三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换 ...
- 团体程序设计天梯赛-练习集-*L1-043. 阅览室
L1-043. 阅览室 天梯图书阅览室请你编写一个简单的图书借阅统计程序.当读者借书时,管理员输入书号并按下S键,程序开始计时:当读者还书时,管理员输入书号并按下E键,程序结束计时.书号为不超过100 ...