前言

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

卫语句

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

策略模式

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

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

策略模式代码模板

package com.zzk.test.strategy.template;

import com.zzk.test.strategy.template.base.Strategy;

/**
* @描述 环境角色
*/
public class Context { /**
* 策略对象
*/
private Strategy strategy; /**
* @param strategy 具体策略对象
*/
public Context(Strategy strategy) {
this.strategy = strategy;
} /**
* @描述 执行策略方法
*/
public void contextInterface() {
strategy.strategyInterface();
}
}
package com.zzk.test.strategy.template.base;

/**
* @描述 抽象策略角色
*/
public interface Strategy { /**
* @描述 策略方法
*/
void strategyInterface();
}
package com.zzk.test.strategy.template;

import com.zzk.test.strategy.template.base.Strategy;

/**
* @描述 具体策略类A
*/
public class ConcreteStrategyA implements Strategy { @Override
public void strategyInterface() {
// TODO Auto-generated method stub
}
}
package com.zzk.test.strategy.template;

import com.zzk.test.strategy.template.base.Strategy;

/**
* @描述 具体策略类B
*/
public class ConcreteStrategyB implements Strategy { @Override
public void strategyInterface() {
// TODO Auto-generated method stub
}
}
package com.zzk.test.strategy.template;

import com.zzk.test.strategy.template.base.Strategy;

/**
* @描述 具体策略类C
*/
public class ConcreteStrategyC implements Strategy { @Override
public void strategyInterface() {
// TODO Auto-generated method stub
}
}

调用者

/**
* @描述 使用策略模式:针对一组算法,将每一个算法封装到具有共同接口的独立的类
*/
public static void useStrategy() {
// 具体使用策略
Strategy strategy = new ConcreteStrategyA();
// 将策略放入环境中并执行策略
new Context(strategy). contextInterface();
}

状态模式

状态模式类图

环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态
抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为
具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为

策略模式代码模板:

package xyz.zeling.test.state.template.base;

/**
* @description 抽象状态角色
* @author zeling
* @date 2018年1月14日 下午8:41:14
*/
public interface State { /**
* @description 处理方法
* @date 2018年1月14日 下午8:41:00
*/
void handle();
}
package xyz.zeling.test.state.template;

import xyz.zeling.test.state.template.base.State;

/**
* @description 具体状态类A
* @author zeling
* @date 2018年1月14日 下午8:45:00
*/
public class ConcreteStateA implements State { @Override
public void handle() {
// TODO Auto-generated method stub
}
}
package xyz.zeling.test.state.template;

import xyz.zeling.test.state.template.base.State;

/**
* @description 具体状态类A
* @author zeling
* @date 2018年1月14日 下午8:45:00
*/
public class ConcreteStateB implements State { @Override
public void handle() {
// TODO Auto-generated method stub
}
}
package xyz.zeling.test.state.template;

import xyz.zeling.test.state.template.base.State;

/**
* @description 具体状态类A
* @author zeling
* @date 2018年1月14日 下午8:45:00
*/
public class ConcreteStateC implements State { @Override
public void handle() {
// TODO Auto-generated method stub
}
}
package xyz.zeling.test.state.template;

import xyz.zeling.test.state.template.base.State;

/**
* @description 状态模式,环境角色类
* @author zeling
* @date 2018年1月14日 下午8:43:58
*/
public class Context { /**
* 状态对象
*/
private State state; /**
* @description 设置状态
* @date 2018年1月14日 下午9:13:20
* @param state 具体状态
*/
public void setState(State state) {
this.state = state;
} /**
* @description 执行策略方法
* @date 2018年1月14日 下午8:43:31
*/
public void request() {
state.handle();
}
}

调用者

    /**
* @description 使用状态模式:状态模式,又称状态对象模式(Pattern of Objects for
* States),状态模式是对象的行为模式。状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样
* @date 2018年1月14日 下午4:04:16
*/
public static void useState() {
// 具体使用状态
State state = new ConcreteStateA();
// 创建环境
Context context = new Context();
// 设置状态并执行
context.setState(state);
context.print();
}

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

讲真,我觉得它们都差不多啊,好难区别啊!!! 
不过,虽然讲不出来它们的区别是什么,但是有个例子可以很好的描述它们的区别

.状态模式:这个模式就好比员工申请离职单的流程,离职单到直接上级,这个状态就是直接上级批示,等直接上级审阅之后,通过了就到下一个状态。这一个个状态对应不同的处理,这是有顺序要求的。
.策略模式:这个模式好比于你假期要出国游玩,有日本、美国、新加坡等国家,你每到一个国家就执行不同的游玩策略,可以先去日本,也可以先去美国,没有顺序要求。

java - 策略模式、状态模式、卫语句,避免多重if-else(转)的更多相关文章

  1. JAVA设计模式:状态模式

    声明:转载请说明来源:http://www.cnblogs.com/pony1223/p/7518226.html 一.引出状态模式 假设我们现在有一个糖果机项目,那么我们知道正常一般糖果机提供给用户 ...

  2. 折腾Java设计模式之状态模式

    原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...

  3. Java设计模式(十) 备忘录模式 状态模式

    (十九)备忘录模式 备忘录模式目的是保存一个对象的某个状态,在适当的时候恢复这个对象. class Memento{ private String value; public Memento(Stri ...

  4. 曾侯乙编钟引发的遐想之Java设计模式:状态模式

    目录 示例 简单例子 改进代码 状态模式 定义 意图 主要解决问题 何时使用 优缺点 曾侯乙编钟 状态模式-命令模式-策略模式 示例 一个类对外提供了多个行为,同时该类对象有多种状态,不同状态下对外的 ...

  5. JAVA设计模式--State(状态模式)

    状态模式(State Pattern)是设计模式的一种,属于行为模式. 定义(源于Design Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要 ...

  6. java设计模式--行为型模式--状态模式

    什么是行为型模式,小编觉得就是对行为的一种描述啦,一种对某种行为模型的定义. 状态模式: 状态模式 概述 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被 ...

  7. Java设计模式之状态模式详解

    (本文由言念小文原创,转载请注明出处) 在实际工作中经常遇到某个对象,处于不同的状态有不同行为逻辑.且状态之间可以相互迁移的业务场景,特别是在开发通信协议栈类软件中尤为多见.<设计模式之禅> ...

  8. java设计模式之状态模式

    状态模式 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类. 状态模式UML图 上下文环境(Context):它定义了客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关 ...

  9. [19/05/02-星期四] GOF23_行为型模式(状态模式、观察者模式、备忘录模式)

    一.状态模式 [状态接口] /*** * 房间"状态"接口 */ package cn.sxt.state; public interface State { void handl ...

  10. 8.js模式-状态模式

    1. 状态模式 var offLightState = function(light){ this.light = light; } offLightState.prototype.buttonWas ...

随机推荐

  1. ORACLE——将多行文本数据转换成一行

    前几天项目中有个到处文件的功能,但是有一个字段存进的数据存在换行情况,导出来的数据会出现错乱的情况,所以需要把换行的数据转换成一行.当然也可以在java程序中实现. 数据库中的数据为: SQL'; A ...

  2. 617A

    #include <stdio.h> int main() { int moves[5]={1,2,3,4,5}; int x; scanf("%d", &x) ...

  3. PowerBI/Excel - PowerQuery数据转换系列 - 如何将多行的值串联到一行 - 行列转换

    Power Query 是做数据转换.数据清洗的利器,不管是在Excel还是PowerBI,如何玩好Power Query是成功建模的必不可少的一步. 今天要get到的一个新技巧:行列转换 如何将多行 ...

  4. 铁大Facebook隐私保护NABCD

    隐私保护功能: N:满足了用户保护自己隐私信息的需求 A:对每一项用户可能需要保护的信息,我们都会添加仅自己可见.指定人可见.部分人可见或所有人可见设置 B:让用户的信息受到更全面的保护,而不仅仅是对 ...

  5. flask hook

    @app.before_first_requestdef before_first_request(): """在第一次请求之前会访问该函数""&qu ...

  6. Python练习:初别Pandas

    # Pandas安装- Anaconda 安装: conda install pandas 或者pip install pandas 参考 http://pandas.pydata.org/ ## S ...

  7. python 之路 day5 - 常用模块

    模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configparser has ...

  8. 2018-2019-2 网络对抗技术 20165305 Exp1 PC平台逆向破解

    2018-2019-2 网络对抗技术 20165305 Exp1 PC平台逆向破解 实验1-1直接修改程序机器指令,改变程序执行流程 先输入objdump -d 20165305pwn2查看反汇编代码 ...

  9. Python 递归计算分数数列

    C语言的课后习题 求数列:2/1,3/2,5/3,8/5,13/8,21/13,...前50项的和 数列规律: 第二项的分母是[前一项分子] 第二项的分子是[前一项分子与分母的和] from frac ...

  10. python中sorted()和set()去重,排序

    前言 在看一个聊天机器人的神经网络模型训练前准备训练数据,需要对训练材料做处理(转化成张量)需要先提炼词干,然后对词干做去重和排序 words = sorted(list(set(words))) 对 ...