java输出不同颜色_Java设计模式-策略模式、状态模式

815756052c3a42c9938c5688880aea1c.png

推荐阅读:

一只Tom猫:都是“Redis惹的祸”,害我差点挂在美团三面,真是“虚惊一场”!

java喵:6大面试技能树:JAVA基础+JVM+算法+数据库+计算机网络+操作系统

前言

当代码中出现多重if-else语句或者switch语句时,

弊端有二:弊端之一:如果这样的代码出现在多处,那么一旦出现需求变更,就需要把所有地方的if-else或者switch代码进行更改,要是遗漏了某一处,那么程序就会出错。弊端之二:代码逻辑难以理解。

卫语句

卫语句的使用,并不能改变前言说的弊端:一旦需求更改,需要修改所有使用更改需求的if-else代码块。不过使用卫语句可以让自己或者代码维护人员很容易的了解代码的含义。

代替异常分支

所谓的异常分支就是普通情况之外的分支,这种情况的下的if-else可以用以下代替。

if (condition)    return obj;

代替多重if-else分支

这个情况的代替方式是可以为

if (isSunshine()) {    // 晴天时处理逻辑}if (isRain()) {    // 下雨时处理逻辑}if (isOvercast()) {    // 阴天时处理逻辑}...

策略模式

使用策略模式可以代替多重if-else和switch语句,让代码维护变得更加简单。 策略模式UML:

  • 环境(Context)角色:持有一个Strategy的引用
  • 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现
  • 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为

策略模式代码模板:

/** * @description 环境角色 */public class Context {     /**     * 策略对象     */    private Strategy strategy;     /**     * @param strategy 具体策略对象     */    public Context(Strategy strategy) {        this.strategy = strategy;    }     /**     * @description 执行策略方法     */    public void contextInterface() {        strategy.strategyInterface();    }}
/** * @description 具体策略类A */public class ConcreteStrategyA implements Strategy {     @Override    public void strategyInterface() {        // TODO Auto-generated method stub    }
/** * @description 具体策略类B */public class ConcreteStrategyB implements Strategy {     @Override    public void strategyInterface() {        // TODO Auto-generated method stub    }
/** * @description 具体策略类C */public class ConcreteStrategyC implements Strategy {     @Override    public void strategyInterface() {        // TODO Auto-generated method stub    }

实例应用:水果有不同种类,每种水果对应不同价格,用策略模式实现。

/** * @description 抽象策略,水果接口 */public interface Fruit {    /**     * @description 输出对应价格     */    void price();
/** * @description 具体策略,苹果类 */public class Apple implements Fruit {     @Override    public void price() {        System.out.println("苹果的价格!");    }
/** * @description 具体策略,香蕉 */public class Banana implements Fruit {     @Override    public void price() {        System.out.println("香蕉的价格!");    }
** * @description 具体策略,梨 */public class Pear implements Fruit {     @Override    public void price() {        System.out.println("梨的价格!");    }
/** * @description 策略环境,输出水果价格 */public class FruitPrice {     /**     * 策略对象     */    private Fruit fruit;     /**     * @param fruit 策略对象     */    public FruitPrice(Fruit fruit) {        this.fruit = fruit;    }     /**     * @description 输出水果价格     */    public void printFruitPrice() {        fruit.price();    }

客户端

/**     * @description 使用策略模式:针对一组算法,将每一个算法封装到具有共同接口的独立的类     */    public static void useStrategy() {        // 具体使用策略        Fruit apple = new Apple();        // 将策略放入环境中并执行策略        new FruitPrice(apple).printFruitPrice();

状态模式

状态模式类图:

说明:

环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态

抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为

具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为

策略模式代码模板:

/** * @description 抽象状态角色 */public interface State {     /**     * @description 处理方法     */    void handle()
** * @description 具体状态类B */public class ConcreteStateB implements State {     @Override    public void handle() {        // TODO Auto-generated method stub    }
/** * @description 具体状态类C */public class ConcreteStateC implements State {     @Override    public void handle() {        // TODO Auto-generated method stub    }
/** * @description 状态模式,环境角色类 */public class Context {     /**     * 状态对象     */    private State state;     /**     * @description 设置状态     * @param state 具体状态     */    public void setState(State state) {        this.state = state;    }     /**     * @description 执行策略方法     */    public void request() {        state.handle();    }

实例应用:橘子有不同颜色,状态不同的橘子颜色不同,用状态模式实现。

/** * @description 状态模式,状态接口 */public interface Orange {    /**     * @description 输出橘子的颜色     */    void printColor();}
** * @description 状态2:青色的橘子 */public class CyanOrange implements Orange {     @Override    public void printColor() {        System.out.println("My color is cyan!");    }
** * @description 橘子状态管理器 */public class OrangeStateManage {     /**     * 橘子的状态     */    private Orange state;     /**     * @description 设置橘子的状态     * @param state     */    public void setState(Orange state) {        this.state = state;    }     /**     * @description 输出当前状态的橘子颜色     */    public void print() {        state.printColor();    }
/** * @description 状态1:红色外观的橘子 */public class RedOrange implements Orange {     @Override    public void printColor() {        System.out.println("My color is red!");    }}
/** * @description 状态3:黄色的橘子 */public class YellowOrange implements Orange {     @Override    public void printColor() {        System.out.println("My color is yellow!");    }

客户端

/**     * @description 使用状态模式:状态模式,又称状态对象模式(Pattern of Objects for     *              States),状态模式是对象的行为模式。状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样     */    public static void useState() {        // 具体使用状态        Orange cyanOrange = new CyanOrange();        // 创建环境        OrangeStateManage orangeStateManage = new OrangeStateManage();        // 设置状态并执行        orangeStateManage.setState(cyanOrange);        orangeStateManage.print();

策略模式和状态模式的比较

讲真,我觉得它们都差不多啊,好难区别啊!!!

不过,虽然讲不出来它们的区别是什么,但是有个例子可以很好的描述它们的区别

状态模式:这个模式就好比员工申请离职单的流程,离职单到直接上级,这个状态就是直接上级批示,等直接上级审阅之后,通过了就到下一个状态。这一个个状态对应不同的处理,这是有顺序要求的。

策略模式:这个模式好比于你假期要出国游玩,有日本、美国、新加坡等国家,你每到一个国家就执行不同的游玩策略,可以先去日本,也可以先去美国,没有顺序要求。

版权声明:本文为CSDN博主「秦岭熊猫」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tianshan2010/article/details/103681617

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/541216.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

abap 添加alv上的工具栏的按钮_神器必会!“世界上最好的编辑器Source Insight”...

前言“Source Insight(以下简称SI)是世界上最好的编辑器”,说这句话不知道会不会出门被打呢?-_- 中国古话说得好,“文无第一,武无第二”,所以不敢说SI是最好的,但是说是“最好的之一”绝对是妥妥的。它以丰…

同一个容器实例可以同时运行在多个宿主机_从零开始学K8s: 3.什么是容器

Kubernetes使用Linux容器技术来实现应用的隔离。因此在深入学习k8s之前,我们需要先学习容器的基础知识以便更好地去理解k8s的原理机制。揭开容器的神秘面纱当一个应用只由较少数量的大组件构成时,完全可以给每个组件分配一个专用的虚拟机,以及…

SpringBoot集成RabbitMq消息队列【附源码】

1. 项目背景 要啥项目背景,就是干!!! SpringBoot版本:2.7.12 2. Rabbit MQ安装 这里讲解使用docker安装RabbitMQ,如果在windows下面安装RabbitMQ,参考下文 【笑小枫的按步照搬系列】Window…

【云栖直播】精彩推荐第3期:个性化推荐系统搭建实践

热门推荐 (1)即将直播持续集成与交付:分层自动化之UI自动化体系建设直播简介:本系列直播由阿里旗下一站式研发提效平台云效策划推出,主要为大家详细介绍阿里巴巴在持续集成和持续交付的最佳实践。 直播讲师&#xff1a…

ensp路由器无法启动_品胜云路由器Breed刷入详细教程,技巧和注意事项,功能大增...

前面发文,介绍过品胜净音云路由器WFR101N功能,硬件配置参数,高清拆解图。主要硬件参数:闪存型号是W25Q128FVSG,容量大小是16M;内存是华邦的W9751G6KB-25,DDR2 SDRAM内存,大小64M&…

wps计算机打印双面输出,在wps中双面打印的方法步骤详解

我们在打印word文档的时候往往都会使用到双面打印,那么今天小编教你怎么在wps中双面打印。希望对你有帮助!WPS双面打印的步骤首先点击wps上的文字选项。找到打印按钮。点击打开之后,会跳出这样一个页面。PS双面打印的步骤图1页面内&#xff0…

判断五个分数等级划分_压力表精度等级怎么算?压力表精度等级划分及检验项目...

压力表是一种典型的轴向精密压力表,是用来测量介质压力的仪表,在工业生产也是常用的仪表,对生产起到了非常重要的作用,压力表的所显示压力的精度,就成了我们非常重要的一个参数。今天小编就来为大家说说压力表精度等级…

cad安装日志文件发生错误_苹果电脑Mac os系统重装时出现“准备安装时发生错误”解决方案...

题外话:自己是个电脑小白,因为自己的MacBook Air 不那么流畅了,就按照其他知乎大佬们说的步骤进行重装电脑。(2017款 MacBook Air 以下就用Air代替) 自己先把电脑重新启动,按照步骤按住commandR&#xff0c…

sass使用相关报错

1. 移动端一像素边框的缩放,我创建了三个文件:mixin.scss , base.scss,index.scss 在index.scss里面引入全局样式文件, 在base.scss文件中编写 根据媒体查询设置不同的缩放比例,报错如下: media…

client netty 主动发数据_netty案例,netty4.1基础入门篇十一《netty udp通信方式案例Demo》...

小傅哥 | https://bugstack.cn 沉淀、分享、成长,让自己和他人都能有所收获。专注于原创专题案例编写,目前已完成的专题有;Netty4.x实战专题案例、用Java实现JVM、基于JavaAgent的全链路监控、手写RPC框架、架构设计专题案例、源码分析等。你…

php-对银行卡号做掩码处理

1.实现代码如下/*** 对银行卡号进行掩码处理* param string $bankCardNo 银行卡号* return string 掩码后的银行卡号*/function formatBankCardNo($bankCardNo){//截取银行卡号前4位$prefix substr($bankCardNo,0,4);//截取银行卡号后4位$suffix substr($bankCa…

echarts 柱状图不显示y坐标轴_Python+matplotlib自定义坐标轴位置、颜色、箭头

图书推荐:《Python程序设计基础与应用》(ISBN:9787111606178),董付国,机械工业出版社图书详情:用书教师可以联系董老师获取教学大纲、课件、源码、教案、考试系统等配套教学资源。使用Pythonnumpymatplotlib这样的组合…

css3浏览,css3支持哪些浏览器?

CSS3 带来众多全新的设计体验,但有一个问题值得考虑:浏览器对 CSS3 特性的兼容情况如何?因为页面最终离不开用浏览器来渲染,并不是所有浏览器都完全支持 CSS3 的特性。有时花时间写的效果只能在特定的浏览器下有效,这意…

移动游戏加载性能和内存管理全解析 学习

https://v.qq.com/iframe/player.html?vido0512etq2vm&tiny0&auto0 转载于:https://www.cnblogs.com/revoid/p/7039232.html

++代码实现 模糊综合算法_干货 | 十大经典排序算法最强总结(内含代码实现)...

一、算法分类十种常见排序算法可以分为两大类:比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。非比较类排序:不通过比较来决定元素间的相对次序&#…

如何恢复osd的auth表中的权限

2019独角兽企业重金招聘Python工程师标准>>> 原因:当你一不小心删掉了osd的auth信息时,重启osd服务,此时ceph -s查看发现osd down 如: [rootceph ~]# ceph osd tree ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIM…

PS打开PSD文档服务器未响应,ps打不开psd文件的解决方法

很多人用ps做作品的时候,经常遇到psd文件打不开的问题,最常见的有三种原因,有两种可以设置解决,另一种是文件损坏,不可恢复。下面是学习小编给大家整理的有关介绍ps打不开psd文件的解决方法,希望对大家有帮…

ajax实现两个aspx跳转,请问ajax执行成功后可以跳转到另一个页面吗?

一只名叫tom的猫通过ajax读取到写好的jsp,另一个jsp可以放framse或者层都可以,显示就行了123456789$.ajax({ type: "POST", //用post方式传输 dataType: "html", //数据格式:json…

Android横竖屏切换View设置不同尺寸或等比例缩放的自定义View的onMeasure解决方案(2)...

Android横竖屏切换View设置不同尺寸或等比例缩放的自定义View的onMeasure解决方案(2)附录文章1以xml布局文件方式实现了一个view在横竖屏切换时候的大小尺寸缩放,实现这种需求,也可以使用自定义View的onMeasure方法实现。比如&…

本地 服务器 文件传输,本地服务器文件传输

本地服务器文件传输 内容精选换一换CDM支持周期性自动将新增文件上传到OBS,不需要写代码,也不需要用户频繁手动上传即可使用OBS的海量存储能力进行文件备份。这里以CDM周期性备份FTP的文件到OBS为例进行介绍。例如:FTP服务器的to_obs_test目录…