20220510
解决方案:类、对象、方法
大概来说,一个程序运行上述游戏需要以下几个部分组成
1.算法
设置一个初始布局状态,打印这个布局状态,当用户想看下一代的时候根据规则更新布局状态并打印当前状态
2.类和对象
一个configuration布局实体/实例/对象,类型是Life,我们让这个对象使用Life的3个方法:initialize将会初始化一个最开始的状态,print打印当前布局,update让布局更新为下一代
一个Clients类,用于访问前面的对象,可以声明前面这些类的实例。一般可以叫做Main活着xxxTest之类的都ok
3.规范
当编写一个客户端程序的时候,一个很重要的点是我们不需要知道数据是如何存储的,也不需要知道这些方法是如何被编程的。这是自顶向下设计非常重要的一个转变,写代码多了就会熟悉这种思路。这通常被称为information hiding
当我们实现Life类的时候,我们才需要决定如何存储这些数据,以及如何实现这些方法,这些数据和方法对Life来说都是私有的,client程序不需要知道这些,只需要访问公开的方法即可
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import java.util.Scanner; public class Main0510_1 { /** * 前置条件:用户指定了初始布局 * 预期结果:根据规则打印所有存活的细胞 * 依赖:Life类和成员方法initialize、print、update */ public static void main(String[] args) { Life conf = new Life(); instructions(); conf.initialize(); conf.print(); System.out.println("是否继续下一代?"); while (userSaysYes()) { conf.update(); conf.print(); System.out.println("是否继续下一代?"); } } private static void instructions() { System.out.println("打印使用指南"); } public static boolean userSaysYes() { Scanner in = new Scanner(System.in); boolean userInput = in.nextBoolean(); return userInput; } } |
编程中一个相当重要的道德行为就是命名规范,尽管数据和算法之前就存在了,但只有当给他们有意义的名字的时候,他们才能被正常的阅读。为了精确的理解每个变量和方法的作用,有时需要给类、变量、方法编写文档来说明。它们的名字应当简洁且清晰的精确表示他们的含义,寻找一个好的变量名并不总是一个简单的工作
使用小写字母l、大写字母O、数字0的时候需要额外的注意,底下是一个蛋疼的例子(吐槽下苹果上对于括号的渲染,也是个大坑)
0 1 2 |
l = 1; x = 1; x = l; x = O; O = 0; |
注释要避免解释代码本身的动作,解释Why,而不是解释How
0 1 2 3 |
count ++ //count自增1 count ++ //增加xxx的计数,这里的xxx是上下文相关的,count的实际含义,虽然我一般会直接用xxxCount来避免这种注释 |
编程原则:
- 让程序的阅读起来更容易,因为一个程序的阅读时间要远多于编写时间
- 不要丢掉全局视野
- 用类来对基础概念进行建模
- 每个方法都应该只做一件事,但做到极致
- 每个类都应该隐藏一些东西
- 保持上下文简洁、如非必要,不要用全局变量
- 尽可能的避免边际效应,如果一定要用全局变量,写文档
编码&测试&重构
stub打桩技术,快速让主程序通过编译或为了方便测试,可以先搭架子
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import java.util.Scanner; public class Main0510_1 { /** * 前置条件:用户指定了初始布局 * 预期结果:根据规则打印所有存活的细胞 * 依赖:Life类和成员方法initialize、print、update */ public static void main(String[] args) { Life conf = new Life(); instructions(); conf.initialize(); conf.print(); System.out.println("是否继续下一代?"); while (userSaysYes()) { conf.update(); conf.print(); System.out.println("是否继续下一代?"); } } private static void instructions() { System.out.println("打印使用指南"); } public static boolean userSaysYes() { Scanner in = new Scanner(System.in); boolean userInput = in.nextBoolean(); return userInput; } } class Life { public void initialize() { } public void print() { } public void update() { } } |
20220510结束,耗时1小时10分钟
顺带一提,vscode Code-runner跑代码乱码可以这样解决
0 1 2 3 4 |
"code-runner.executorMap": { "java": "cd $dir && javac -encoding utf-8 $fileName && java -Dfile.encoding=UTF-8 $fileNameWithoutExt" } |
0 Comments