面向对象设计模式:Java中的状态模式代码示例

网上有很多关于使用面向对象模式的文章和视频。如果您找不到一个真正好的示例,那么就很难真正理解它。当我和我8岁的儿子一起骑自行车时,我总是提醒他在骑上坡时加速,在骑平坡或下坡时要减速。这种传动装置机制是解释如何使用状态模式的一个很好的例子。在本教程中,我将通过一个骑自行车的示例演示State Patterns(状态设计模式)。我希望它能与你的学习方式产生共鸣,记住它,以供以后参考。

首先,我需要一个自行车类。这应该很简单:

public class Bike {
GearState gearState;
public Bike(){
gearState = new FirstGear(this);
}
public void gearUp(){
gearState.gearUp();
}
public void gearDown(){
gearState.gearDown();
}
}

我一直在尽可能简单的自行车类。上面的Bike类是使用State模式实现的。只要您能够使用许多“如果”或“切换”条件,就可以在其中使用所有与状态相关的齿轮代码。如果有许多状态,则很难维持后者。如果您需要维护一些状态,那么状态模式将使您的设计复杂化。

正如您在上面的代码中看到的,我们有GearState,它只是一个抽象类,您将在下面看到完整的代码。这辆自行车可以从GearState扩展开来,但这并不是“Is A”关系。这就是为什么我没有扩展,因为在状态模式中,扩展状态接口不是一种常见的实践。

public abstract class GearState {
Bike bike;
GearState(Bike bike){
this.bike = bike;
}
public abstract void gearUp();
public abstract void gearDown();
}

一辆变速自行车可以有很多齿轮,但是为了简单起见,这辆自行车只有三个齿轮:FirstGear , SecondGear , 和 ThirdGear 。下面是gears的实现:

class FirstGear extends GearState{
FirstGear(Bike bike) {
super(bike);
}
@Override
public void gearUp() {
System.out.println("Moving Up from FirstGear to SecondGear");
bike.gearState = new SecondGear(bike);
}
@Override
public void gearDown() {
System.out.println("Already in the FirstGear - cannot go lower");
}
}

如果你尝试减速,当你在第一个齿轮(FirstGear),你没有低于第一个齿轮。因此,它什么都不做。但是,当你试着加速时,自然地,你会移动到第二个齿轮位置(SecondGear)。下面的代码很好地演示了这一点。

让我们看看其他的齿轮状态。

class SecondGear extends GearState{
SecondGear(Bike bike) {
super(bike);
}
@Override
public void gearUp() {
System.out.println("Moving Up from SecondGear to ThirdGear");
bike.gearState = new ThirdGear(bike);
}
@Override
public void gearDown() {
System.out.println("Moving Down from SecondGear to FirstGear");
bike.gearState = new FirstGear(bike);
}
}
class ThirdGear extends GearState {
public ThirdGear(Bike bike) {
super(bike);
}
@Override
public void gearUp() {
System.out.println("Already in the ThirdGear - cannot go higher");
}
@Override
public void gearDown() {
System.out.println("Moving Down from ThirdGear to SecondGear");
bike.gearState = new SecondGear(bike);
}
}

现在,是时候看到它运行了。

下面是演示不同状态变化的示例方法。

public class StateDemo {
public static void main(String[] args) {
Bike bike = new Bike();
bike.gearDown();
bike.gearUp();
bike.gearUp();
bike.gearUp();
bike.gearUp();
bike.gearDown();
bike.gearDown();
bike.gearDown();
}
}

当您运行上面的代码时,控制台输出如下:

Already in the FirstGear — cannot go lower Moving Up from FirstGear to SecondGear Moving Up from SecondGear to ThirdGear Already in the ThirdGear — cannot go higher Already in the ThirdGear — cannot go higher Moving Down from ThirdGear to SecondGear Moving Down from SecondGear to FirstGear Already in the FirstGear — cannot go lower

结论

如果有很多状态需要处理,并且它们之间有一些复杂的关系,那么状态模式就是正确的解决方案。它会让你的主类(在我们这个例子中是自行车,)专注于实现自己职责的工作。如果您想添加或删除新状态,会很容易而且不影响其它类。

原文发布于微信公众号 - 程序你好(codinghello)

原文发表时间:2018-08-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏H2Cloud

Boost asio 心得笔记

Boost asio中有两点用的不爽: 1. asio中的所有对象都引用io_service 2. async_write还要自己保证内存在completed之...

42370
来自专栏CSDN技术头条

嵌入式开发中静态代码分析器的七种用途

当前标准的C语言编译器存在普遍只能找出代码中潜在的缺陷,而对程序方案设计并没有效。使用静态代码分析器有助于提升固件和捕获编译器难以察觉的问题。以下是每一位嵌入式...

23870
来自专栏安恒网络空间安全讲武堂

Writeup丨国赛线上初赛解题第二波~

17040
来自专栏用户2442861的专栏

Python基础学习笔记之(一)(华工大神)

       前段时间参加微软的windows Azure云计算的一个小培训,其中Python被用的还是蛮多的。另外,一些大公司如Google(实现web爬虫...

20010
来自专栏跟着阿笨一起玩NET

EF中Repository模式应用场景

   在DDD领域构架系统中,为了将领域模型从领域逻辑层中和数据映射层之间解耦出来,我们引用到了Repository模式,属于属于泛型编程中一个比较常用的模式,...

40030
来自专栏牛客网

携程Java后台开发三面面经

前言 携程是我面试的第一个互联网公司,投递的岗位是后台开发实习生,总共面了三面,止步于人才库。中间兜兜转转,复杂的心理活动,不足与外人道也。唯有面试的技术部分与...

46140
来自专栏Gcaufy的专栏

async/await 带你逃离回调地狱

不曾见过天堂就不会畏惧地狱,async/await是目前尝试过的最好的异步回调解决方案,本文通过详细步骤给大家讲解。

57000
来自专栏IT大咖说

关于 Unicode 每个程序员应该知道的 5 件事

摘要 Unicode是一个令人难以置信的有用标准,它能使全世界的计算机、智能手机和智能手表以同样的方式显示相同的信息。不幸的是,它的复杂性使它成为了欺诈分子和恶...

29270
来自专栏LET

CPU SIMD简介

之前的两篇文章,分别介绍了CPU和CPU Cache两个话题,性能是永恒的核心。我们也谈到了优化CPU性能面临的三堵墙:

22530
来自专栏我的小碗汤

使用pprof优化golang性能

Donald E.Knuth说过一句非常著名的话,过早的优化是万恶之源。原文如下:

21440

扫码关注云+社区

领取腾讯云代金券