这篇文章缘起于前几天微博上有关动态语言与静态语言的讨论,因为有几个编程高手参加,所以能看到一些特别有启发性的发言。本文主要是下面这一条微博的读后感,也是我的练习与思考。

关于动态语言与静态语言,有很多比较和讨论它们的文章,但大部分都没有抓住重点。而上面一条微博,提到了一个很好的切入点,那就是「状态模式(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相关推荐

  1. python 状态模式_使用状态模式自由切换登录状态

    日常开发中,登录和未登录两种状态分别有不同的操作,比如登录后才能评论.收藏.支付购买和编辑资料等操作.我们网购时看到心仪的商品,如果处于登录状态,可以加购物车或直接购买,否则会跳转到登录页面,登录后再 ...

  2. java设计与模式_设计模式《JAVA与模式》之状态模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述状态(State)模式的: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为 ...

  3. java改写模式_Java基于状态模式实现的文档编辑模式切换功能实例

    本文实例讲述了Java基于状态模式实现的文档编辑模式切换功能.分享给大家供大家参考,具体如下: 一 模式定义 状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来就像是改变了其类. 二 ...

  4. java 状态模式 重试_java状态模式

    一:状态模式 描述: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式. 状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对 ...

  5. 8-设计模式之行为型模式二(状态模式、观察者模式、中介者模式)

    设计模式之行为型模式二(状态模式.观察者模式.中介者模式) 6.5 状态模式 6.5.1 概述 6.5.2 结构 6.5.3 案例实现 6.5.4 优缺点 6.5.5 使用场景 6.6 观察者模式 6 ...

  6. 《JAVA与模式》之状态模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述状态(State)模式的: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为 ...

  7. Java描述设计模式(21):状态模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 变色龙是爬行动物,是非常奇特的动物,它有适于树栖生活的种种特征和行为,身体也会随着环境的变化而变化出适应环境的颜色 ...

  8. java 中介模式_中介者模式

    什么是中介者模式? 在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群.短信平台和房产中介.不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中间平台与其他Q ...

  9. java 装饰器_装饰器模式(Java)

    什么是装饰器模式? 装饰器模式允许你向一个现有的对象添加新的功能,同时又不改变其结构,它是作为现有的类的一个包装.这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额 ...

最新文章

  1. 爆火的深度学习面试书现可白嫖!GitHub上线2周1.5K Star,之前售价146元
  2. CV:基于keras利用cv2自带两步检测法对《跑男第六季第五期》之如花片段(或调用摄像头)进行实时性别脸部表情检测
  3. android 支付宝月账单 统计图_2019年你抢了多少微信红包?花了多少?(微信账单查看教程)...
  4. SharePoint 2007 做Migration后用户处理
  5. Azure SQL Database (1) 用户手册
  6. 面试官系统精讲Java源码及大厂真题 - 22 ArrayBlockingQueue 源码解析
  7. 万网空间的数据库配置方法
  8. vSAN其实很简单-一张图搞清楚不同vSAN版本之间的功能差异
  9. 如何查看域控是谁,域控是哪台机器
  10. Vue : Expected the Promise rejection reason to be an Error
  11. 矩阵运算--特征矩阵
  12. 三菱伺服驱动器示例_三菱伺服电机+编码器(伺服控制器)的接线示例
  13. QQ坦白说使用Fiddler抓包获取json
  14. vb 分类汇总方法_高中数学19种解题方法+易错知识分类大汇总!
  15. 穷举查找之旅行商问题、背包问题、分配问题
  16. 加息靴子落地铁矿石继续反弹,甲醇认购大涨,苹果10-01大跳水2022.5.5
  17. 人生第一篇博客,欢迎大佬莅临指导!
  18. 二叉树(1.二叉树的概念堆)
  19. virtualbox 实现虚拟机和宿主机互通
  20. CMD命令行简单学习总结

热门文章

  1. 开源之夏2022携手Casbin社区,邀你参与项目开发
  2. Linux 系统监控工具链
  3. VC2010----调试C语言工程建立
  4. 第4次Python作业 吴为橦
  5. php 识别图片五星好评,基于jquery实现五星好评
  6. 撰写优质软文文案的写作技巧
  7. Openlayers 聚合图、权重聚合图以及聚合图点击事件
  8. 基于flask的看图猜成语小程序
  9. NSX ALB + Harbor + OpenShift 4.8 UPI安装配置实验笔记系列目录
  10. csv乱码 ftp_php读取csv文件后,uft8 bom导致在页面上显示出现问题的解决方法