[转载] 康威的人生游戏与轻量级模式
参考链接: 康威的人生游戏(Python实现)
从功能和技术的角度来看,Conway的“生活游戏”都非常有趣。
这可以解释为什么它经常用于代码撤退 。 代码撤退是一种有趣的学习方法。
几乎每次与新对一起工作都会为您带来新见解,这真是令人惊讶。
在我参加的最后一次代码务虚会上,我的一对建议我们对单元格使用Flyweight模式 :
flyweight是一个共享对象,可以同时在多个上下文中使用。 在每个上下文中,flyweight都充当一个独立的对象-与未共享的对象实例是无法区分的。
当《 设计模式》一书(包含上面的引文)问世时,我记得有很多啊哈。 看到我以前使用过的所有这些模式,并最终为其命名,真是太酷了,这样我可以与同龄人更有效地讨论它们!
但是,当我阅读有关飞重的信息时,我并没有感到惊讶。 书中的示例在文本编辑器中共享字符对象,当时似乎有些牵强。 但是,此示例与“生命游戏”网格中的单元格并无不同,因此我很高兴地沿用了他们俩的想法,探索了该模式在这种情况下的适用性。
代码撤退结束后,我进一步考虑了该模式。 (这通常是代码撤退真正开始起作用的地方。)
实际上,我们一直在使用潜在的重量级:布尔值。 布尔值是只有两个实例的类,可以轻松共享这些实例。 在Java中,它们不是: new Boolean(true) != new Boolean(true) 。 但是, Boolean类确实为可用于共享的实例提供了两个常量TRUE和FALSE 。
那让我开始考虑将Enum用作飞行重量。 大多数时候,我使用枚举对相关但互斥的常量进行分组,例如一周中的几天。 但是,Java中的Enum可以定义方法:
public enum Cell {
ALIVE(true), DEAD(false);
private final boolean alive;
private Cell(boolean alive) {
this.alive = alive;
}
public boolean isAlive() {
return alive;
}
public Cell evolve(int numLiveNeighbors) {
boolean aliveInNextGeneration = alive
? 2 <= numLiveNeighbors && numLiveNeighbors <= 3
: numLiveNeighbors == 3;
return aliveInNextGeneration ? ALIVE : DEAD;
}
}
代码撤退的有趣部分之一是,在某些会话中,您将对工作方式有所限制。 这样的约束迫使您更具创造力,并思考超出通常使用的技术范围。
在这种情况下有趣的一个约束是不使用任何条件,例如if或switch语句或三元运算符。 该约束背后的想法是迫使您用多态替换条件语句 ,使您的程序更加面向对象。
我看到的保留当前Cell枚举而不使用条件的唯一方法是引入映射:
public enum Cell {
ALIVE(true), DEAD(false);
private final boolean alive;
private static final Map<Boolean, Map<Integer, Cell>>
NEXT = new HashMap<>();
static {
Map<Integer, Cell> dead = new HashMap<>();
dead.put(0, DEAD);
dead.put(1, DEAD);
dead.put(2, DEAD);
dead.put(3, ALIVE);
dead.put(4, DEAD);
dead.put(5, DEAD);
dead.put(6, DEAD);
dead.put(7, DEAD);
dead.put(8, DEAD);
dead.put(9, DEAD);
NEXT.put(false, dead);
Map<Integer, Cell> alive = new HashMap<>();
alive.put(0, DEAD);
alive.put(1, DEAD);
alive.put(2, ALIVE);
alive.put(3, ALIVE);
alive.put(4, DEAD);
alive.put(5, DEAD);
alive.put(6, DEAD);
alive.put(7, DEAD);
alive.put(8, DEAD);
alive.put(9, DEAD);
NEXT.put(true, alive);
}
private Cell(boolean alive) {
this.alive = alive;
}
public boolean isAlive() {
return alive;
}
public Cell evolve(int numLiveNeighbors) {
return NEXT.get(alive).get(numLiveNeighbors);
}
}
这种方法可行,但不是很优雅,并且随着可能性的增加而失效。 显然,我们需要更好的选择。
摆脱条件的唯一方法是摆脱单元格的布尔状态。 这意味着我们需要为两个实例使用不同的类,以便类型隐式体现状态。 反过来,这意味着我们需要一个工厂来向客户端隐藏这些类:
public interface Cell {
boolean isAlive();
Cell evolve(int numLiveNeighbors);
}
public class CellFactory {
private static final Map<Boolean, Cell> CELLS
= new HashMap<>();
static {
CELLS.put(false, new DeadCell());
CELLS.put(true, new AliveCell());
}
public static Cell dead() {
return cell(false);
}
public static Cell alive() {
return cell(true);
}
static Cell cell(boolean alive) {
return CELLS.get(alive);
}
}
class DeadCell implements Cell {
@Override
public boolean isAlive() {
return false;
}
@Override
public Cell evolve(int numLiveNeighbors) {
return CellFactory.cell(numLiveNeighbors == 3);
}
}
class AliveCell implements Cell {
@Override
public boolean isAlive() {
return true;
}
@Override
public Cell evolve(int numLiveNeighbors) {
return CellFactory.cell(numLiveNeighbors == 2
|| numLiveNeighbors == 3);
}
}
的确,当您查看Flyweight模式时,您会看到建议的结构包含一个flyweight工厂,该工厂创建实现普通flyweight接口的具体flyweight类的实例。
感谢代码撤退和我的合作伙伴,我现在知道为什么。
翻译自: https://www.javacodegeeks.com/2014/04/conways-game-of-life-and-the-flyweight-pattern.html
[转载] 康威的人生游戏与轻量级模式相关推荐
- 【项目经理之修炼(7)】《基础篇》人生游戏中的神器——谦虚
作者: 孙继滨 "一封邮件究竟能够起多大的作用呢??" 大家有时候可能会产生这样的疑问. 史记有过这样的记载: ---------------------------------- ...
- 2012中国移动社交游戏市场盈利模式探讨
2012年中国移动社交游戏市场盈利模式探讨 来源:艾媒网 作者:庄周 2012-04-18 11:13:19 [ 5124阅读 0评论 ] 内容摘要:伴随着中国3G网络的迅速发展与普及,网络社交活动也 ...
- javascript开发HTML5游戏--斗地主(单机模式part3)
最近学习使用了一款HTML5游戏引擎(青瓷引擎),并用它尝试做了一个斗地主的游戏,简单实现了单机对战和网络对战,代码可已放到github上,在此谈谈自己如何通过引擎来开发这款游戏的. 客户端代码 服务 ...
- javascript开发HTML5游戏--斗地主(单机模式part2)
最近学习使用了一款HTML5游戏引擎(青瓷引擎),并用它尝试做了一个斗地主的游戏,简单实现了单机对战和网络对战,代码可已放到github上,在此谈谈自己如何通过引擎来开发这款游戏的. 客户端代码 服务 ...
- 游戏设计模式——黑板模式
目录 黑板(Blackboard) 定义 好处 缺点 额外功能 一个游戏使用黑板模式的例子 其他使用黑板模式的例子 小结 黑板模式的C++简易实现 黑板模式的C#实现 参考 黑板(Blackboard ...
- Python之模拟职场人生游戏
题目:模拟人生 要求:1.至少有两个角色 2.玩的过程中,有冲突 3.根据不同的交互,产生不同的行为. 4.一定要用到面向对象语法和思想 1.解题思路 创建一个类,赋予角色不同的方法,使用面向对象思想 ...
- 一年突破3亿游戏安装量 小米游戏双发行模式助力游戏开发者
2020年,全球市场迎来了颠覆式的新格局,挑战与机遇并存.一方面,疫情导致大量消费者居家隔离,线上业务迎来了爆发式增长;另一方面,文化冲突.数据隐私.地缘关系等因素对海外业务都增加了更多不确定性.对于 ...
- 转载一个手机RPG游戏制作工具,仿造RPGXP写的
转载一个手机RPG游戏制作工具,仿造RPGXP写的 有朋友问有没有脚本编辑功能,大家注意啦: 有脚本编辑功能,可视化界面编辑脚本,和RMXP一样 经过一年的开发,手机RPG游戏制作工具--MobieG ...
- java游戏杀怪物_我的人生游戏 java知识点关卡之java基本类型怪物攻略
人生如游戏,掌握了方方面面的技能知识后方能解决一个个场景下的问题,一步步走上人生巅峰.<我的人生游戏>就是一款将人生中暗含的各种能力培养显性化的游戏,帮你完善技能,积累经验,增加人生战斗力 ...
最新文章
- 正则表达式学习神器!
- const 和 static 的作用
- Perl文件句柄引用
- java小数换成字符实现加法_第一、二次笔记总结
- static_cast、dynamic_cast、reinterpret_cast、和const_cast
- 移动端手势库设计与实践
- 25个个免费英文文献下载网站!
- CS61C 学习笔记 --实时更新
- mysql建立唯一索引升序_MySQL数据库SQL优化技巧六之唯一索引
- 关于python程序格式的描述_关于Python程序格式框架的描述,以下选项中错误的是...
- 解决手机浏览器无法显示本地html文件
- 梯度下降算法的细节补充(凸函数, 导数, 偏导数,梯度, 方向导数以及负梯度下降最快背后的泰勒身影)
- 阿里云ECS七天训练营-搭建FTP
- YOLOv5的项目实践 | 手势识别项目落地全过程(附源码)
- mysql left outer join_关于mysql中的left join和left outer join的区别
- 亲历骗子通过闲鱼、江苏猎宝网络科技股份有限公司进行诈骗!
- 计算机编程语言及C语言简介,编程语言基础:C语言
- 腾讯云https证书部署nginx
- [Ubuntu 16.04] [Memos] install samba
- CentOS7 搭建Janus服务
热门文章
- 【PAT甲】1051 Pop Sequence (25分)判断出栈顺序的合法性
- Office Word2019您正试图运行的函数包含有宏或需要宏语言
- 电大计算机专业毕业自我鉴定,电大毕业生计算机专业自我鉴定
- eclipse配置python开发环境_Eclipse中配置python开发环境详解
- JQueryDOM之修改节点
- RSA解密Matlab,RSA加密算法--matlab
- [leetcode] 413. 等差数列划分
- Codeforces Round #197 (Div. 2): D. Xenia and Bit Operations(线段树)
- bzoj 1675: [Usaco2005 Feb]Rigging the Bovine Election 竞选划区(暴力)
- [debug+Python] 复制字典不能直接用 ‘=’,要用dict_name.copy()