java 与 模式_从状态模式看 JavaScript 与 Java
这篇文章缘起于前几天微博上有关动态语言与静态语言的讨论,因为有几个编程高手参加,所以能看到一些特别有启发性的发言。本文主要是下面这一条微博的读后感,也是我的练习与思考。
关于动态语言与静态语言,有很多比较和讨论它们的文章,但大部分都没有抓住重点。而上面一条微博,提到了一个很好的切入点,那就是「状态模式(State Pattern)」。
状态模式:蝙蝠侠/布鲁斯·韦恩
蝙蝠侠(英语:Batman)是一名出现于DC漫画的虚构超级英雄角色,由鲍勃·凯恩和比尔·芬格创作。他的名字叫 Bruce,是一位美国亿万富翁,这是他的正常身份,用于正常生活,例如进行参加宴会之类的活动。他的另一个身份是 Batman,是打击犯罪的黑暗骑士。
这是一个状态模式的好示例,我用 Java 和 JavaScript 各写了一个示例,体会体会「极其繁琐」与「非常简单」。
极其繁琐:Java 版本
目录结构:
com
|-- tianfangye
|-- Client.java
|-- person
|-- Person.java
|-- state
|-- BatmanState.java
|-- BruceState.java
|-- IState.java
Person.java
package com.tianfangye.person;
import com.tianfangye.state.IState;
import com.tianfangye.state.BruceState;
public class Person {
// 当前状态
private IState state;
public Person() {
this.state = new BruceState();
}
// 设置当前状态
public void changeState(IState state) {
this.state = state;
}
// 改变状态(变身)
public void convertState() {
this.state.convertState(this);
}
// 开始行动
public void takeAction() {
this.state.doActivities();
}
}
IState.java
package com.tianfangye.state;
import com.tianfangye.person.Person;
public interface IState {
// 转换状态
public void convertState(Person person);
// 执行活动
public void doActivities();
}
BruceState.java
package com.tianfangye.state;
import com.tianfangye.person.Person;
public class BruceState implements IState {
private String name = "- Bruce -";
// 转换状态 public void convertState(Person person) {
person.changeState(new BatmanState());
}
// 执行活动 public void doActivities() {
System.out.println(this.name + " <> " + "参加宴会");
}
}
BatmanState.java
package com.tianfangye.state;
import com.tianfangye.person.Person;
public class BatmanState implements IState {
private String name = "- Batman -";
// 转换状态 public void convertState(Person person) {
person.changeState(new BruceState());
}
// 执行活动 public void doActivities() {
System.out.println(this.name + " <> " + "打击犯罪");
}
}
Client.java
package com.tianfangye;
import com.tianfangye.person.Person;
public class Client {
public static void main(String[] args) {
Person person = new Person();
person.takeAction();
person.convertState();
person.takeAction();
}
}
程序输出:- Bruce - <> 参加宴会
- Batman - <> 打击犯罪
关于状态模式的实现,GoF 的 Design Patterns 里面提到过一些需要考虑的方面,其中之一是「谁来定义状态的转换」。可以由状态的使用者(Person)实现,也可以由每个状态各自实现,各有利弊。上例由每个状态各自实现,接下来的 JavaScript 示例也是这种选择(对于示例程序,另一种实现更简单)。
非常简单:JavaScript 版本
const state = {
_Bruce: {
name: "- Bruce -",
convertState() {
this.identity = state._Batman;
},
takeAction() {
window.console.log(`${this.name}<> 参加宴会`);
}
},
_Batman: {
name: "- Batman -",
convertState() {
this.identity = state._Bruce;
},
takeAction() {
window.console.log(`${this.name}<> 打击犯罪`);
}
}
};
const person = {
identity: state._Bruce,
convertState() {
this.identity.convertState.call(this);
},
takeAction() {
this.identity.takeAction();
}
};
person.takeAction();
person.convertState();
person.takeAction();
程序输出:- Bruce - <> 参加宴会
- Batman - <> 打击犯罪
可以看到,相比静态语言的版本,动态语言的版本竟是如此浑然天成!甚至不是在实现「设计模式」,只是对语言特性的正常使用而已。所以,什么是设计模式?聪明人应该想通了——设计模式是一个衍生问题,不是本质问题。本质问题是程序设计,是静态语言与动态语言,是静态类型与动态类型,是编程语言抽象。
@vczh的一个知乎回答对这一点讲得很透彻:
显而易见,类型是个大问题!动态语言能做到非常简洁是由于动态类型系统的灵活性。它们在相当大的程度上简化了程度设计,也就是所谓的「非常简单」。要明白,这里的「简单」与「复杂」并不是指代码量的多少,也不是指语言特性使用的多少,而是指花费在程序设计上面的心思的多少。具体到本例,主要是下面两点:动态类型:不需要花心思去搞定类型检查。
运行时绑定上下文的 this 对象:不需要将有状态的对象传来传去。
当然,这些灵活性并非没有代价(性能)。另外,关于动态语言与静态语言的选择,一直有很多工程问题上的争议(从文章开头的微博往下探索,可以找到大段这方面的争论)。我个人对于动态语言、静态语言没有明显偏好,只是喜欢把问题弄清楚——不论有没有偏好,偏好强烈还是微弱,这都是首要的一步。
java 与 模式_从状态模式看 JavaScript 与 Java相关推荐
- python 状态模式_使用状态模式自由切换登录状态
日常开发中,登录和未登录两种状态分别有不同的操作,比如登录后才能评论.收藏.支付购买和编辑资料等操作.我们网购时看到心仪的商品,如果处于登录状态,可以加购物车或直接购买,否则会跳转到登录页面,登录后再 ...
- java设计与模式_设计模式《JAVA与模式》之状态模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述状态(State)模式的: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为 ...
- java改写模式_Java基于状态模式实现的文档编辑模式切换功能实例
本文实例讲述了Java基于状态模式实现的文档编辑模式切换功能.分享给大家供大家参考,具体如下: 一 模式定义 状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来就像是改变了其类. 二 ...
- java 状态模式 重试_java状态模式
一:状态模式 描述: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式. 状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对 ...
- 8-设计模式之行为型模式二(状态模式、观察者模式、中介者模式)
设计模式之行为型模式二(状态模式.观察者模式.中介者模式) 6.5 状态模式 6.5.1 概述 6.5.2 结构 6.5.3 案例实现 6.5.4 优缺点 6.5.5 使用场景 6.6 观察者模式 6 ...
- 《JAVA与模式》之状态模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述状态(State)模式的: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为 ...
- Java描述设计模式(21):状态模式
本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 变色龙是爬行动物,是非常奇特的动物,它有适于树栖生活的种种特征和行为,身体也会随着环境的变化而变化出适应环境的颜色 ...
- java 中介模式_中介者模式
什么是中介者模式? 在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群.短信平台和房产中介.不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中间平台与其他Q ...
- java 装饰器_装饰器模式(Java)
什么是装饰器模式? 装饰器模式允许你向一个现有的对象添加新的功能,同时又不改变其结构,它是作为现有的类的一个包装.这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额 ...
最新文章
- 爆火的深度学习面试书现可白嫖!GitHub上线2周1.5K Star,之前售价146元
- CV:基于keras利用cv2自带两步检测法对《跑男第六季第五期》之如花片段(或调用摄像头)进行实时性别脸部表情检测
- android 支付宝月账单 统计图_2019年你抢了多少微信红包?花了多少?(微信账单查看教程)...
- SharePoint 2007 做Migration后用户处理
- Azure SQL Database (1) 用户手册
- 面试官系统精讲Java源码及大厂真题 - 22 ArrayBlockingQueue 源码解析
- 万网空间的数据库配置方法
- vSAN其实很简单-一张图搞清楚不同vSAN版本之间的功能差异
- 如何查看域控是谁,域控是哪台机器
- Vue : Expected the Promise rejection reason to be an Error
- 矩阵运算--特征矩阵
- 三菱伺服驱动器示例_三菱伺服电机+编码器(伺服控制器)的接线示例
- QQ坦白说使用Fiddler抓包获取json
- vb 分类汇总方法_高中数学19种解题方法+易错知识分类大汇总!
- 穷举查找之旅行商问题、背包问题、分配问题
- 加息靴子落地铁矿石继续反弹,甲醇认购大涨,苹果10-01大跳水2022.5.5
- 人生第一篇博客,欢迎大佬莅临指导!
- 二叉树(1.二叉树的概念堆)
- virtualbox 实现虚拟机和宿主机互通
- CMD命令行简单学习总结