Day01 - 缘起:怎麽了?为什麽?如何掌握过於自由的程序码?

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” – Martin Fowler

程序码是自由的、弹性的、灵活多变的~

在 JavaScript 的世界尤其是

但随着商业逻辑、应用场景越来越复杂,程序码逐渐庞大

除了能运作之外,我们需要考量的东西越来越多,如系统可靠度、信心(意思是不怕坏掉、不怕bug),系统安全性、系统效能等

以整体软件工程要考量的维度,越来越多。

思考看看以下一些问题

以电商交易举例

电商的订单阶段,买家提交订单(给卖家先确认库存),卖家确认有货可成立点选同意,订单进入等待付款,付款完成收帐後进入等待发货仓储人员配货、安排物流,送达目的地後等待取件,取件完成後订单交易完成

简单归纳

提交 → 待付款 → 待发货 → 待取件 → 交易完成

实务考量

上述一系列流程,用文字叙述看似单纯,但在程序码实作的过程中,需要考量的东西很多,最直接可以想到的就是一些简单的防御。比如说我们要确保还没付款时,程序码没办法接触到等待发货相关的通知、操作与执行。或卖家还没确认成立订单,不能进行扣款等。

以游戏开发举例

举实际应用场景,假设我们今天要设计一个2D RPG游戏,我们必须撰写玩家操纵角色的行为

开发角色移动模组

https://img.craftpix.net/2017/10/2D-Game-Police-Character-Free-Sprite-Sheets.gif

规格

  • 按下 ⇦、⇨ 可控制玩家移动
  • 按下 B 是跳跃
  • 长按 ⇩ 是匍匐前进 → 放开 ⇩ 是起身

1.实作跳跃

https://ithelp.ithome.com.tw/upload/images/20210916/20130721V6OathELrO.png

if(input == PRESS_B){
  // 「实作」计算、画出跳跃的画面,图片从站立换成跳跃
}

发现 bug 了吗(或许对你的游戏设计不是)?假如角色现在已经是正在跳跃,如果再按一次 B ,就会在空气中再继续往上跳

1.1 加入防御 - 空气跳跃(连续跳跃)

因此我们势必要加入一个 flag 来判断是不是正在 跳跃中 ( isJumping )

if(input == PRESS_B){
  if(!isJumping){
    isJumping = true // 将 flag 跳耀中,转为 true
    // 跳
  }
}

2. 实作匍匐前进

https://ithelp.ithome.com.tw/upload/images/20210916/20130721BL45s6O4hw.png

长按 ⇩ ,进入匍匐前进

if (input == PRESS_DOWN){
  // 匍匐前进,换成匍匐前进的图片
}

2.1 加入防御 - 跳跃不能直接变匍匐前进

接着,因为跳跃中不能匍匐前进

 if (input == PRESS_DOWN){
  if(!isJumping){
    // 匍匐前进,换成匍匐前进的图片
  }
}

2.2 与前面跳跃整合,这里从 if 改接 Jump 後的 else if

if(input == PRESS_B){
  // 跳
} else if (input == PRESS_DOWN){
  if(!isJumping){
    // 匍匐前进,换成匍匐前进的图片
  }
}

2.3 加入判断 - 匍匐及站立

放开 ⇩ ,为了恢复站立(我们怎麽知道是不是匍匐中),是不是又要加一个flag 匍匐中( isCrawling )

if(input == PRESS_B){
  // 跳
} else if (input == PRESS_DOWN){
  if(!isJumping){
     isCrawling = true
    // 匍匐前进,换成匍匐前进的图片
  }
} else if (input == RELEASE_DOWN){
  if(isCrawling){
     isCrawling = false
    // 恢复站姿
  }
}

这里是完整的吗、正常的吗?看到这我己经心累了QQ 看得出有 Bug 吗?

2.4 加入防御 - 匍匐不能直接变跳跃

假如我们在匍匐前进时,按下 B 跳跃,因为 isCrawling 还是 true ,我们会看到主角是俯卧的样子飞到空中,所以我们跳跃的logic 判断势必又要回去加点预防

if(input == PRESS_B){
  if(!isJumping && !isCrawling){
    isJumping = true // 将 flag 跳耀中,转为 true
    // 跳
  }
} else if (input == PRESS_DOWN){
  if(!isJumping){
     isCrawling = true
    // 匍匐前进,换成匍匐前进的图片
  }
} else if (input == RELEASE_DOWN){
  if(isCrawling){
     isCrawling = false
    // 恢复站姿
  }
}

“ Code is like humor. When you have to explain it, it’s bad.” – Cory House

假如有个新人今天要人接手这份程序码,这种因为商业需求的防护与连贯,不断在 if/ else 中增添逻辑判断,需要思考很多东西。

比如 为什麽跳跃的行为还要加入 isCrawling,去判断这行 if(!isJumping && !isCrawling)

为了交接顺利、好维护,我们势必要增加一些程序码注解、写好文件等等。

而且从上述的开发过程中,我们也发现,其实这样子的开发模式,很容易漏思考一些东西,或者随着新需求的出现,我们必须回去修改既有的逻辑。

因为我们的程序码太弹性???程序码太诚实???程序码太笨???

下一篇让我们来思考一下为什麽有这个问题的产生、我们可以怎麽预防?


小结

订单RPG 角色的移动,这 2 个例子,描述在复杂的软件应用、系统中,会面临的挑战。
以及我们尝试如何去克服这个困难

  • 透过储存 boolean flag 进变数,记忆状态
  • 透过一系列 if / else 判断状态、进行防呆)

参考文献

图片引用


<<:  Day2 甚麽是Vue?

>>:  OpenStack Neutron 介绍 — OVS Self-service Networks

Day 07 - 导流专家Route 53

来到了第七天,今天让我们来一起看看Route 53吧 Route 53帮那些事情? 有了Route ...

[Day5]Count on Cantor

今天要讲的题目是Count on Cantor 先付上程序码 import java.util.; ...

部署model on seldon(MinIO)

上一篇我们已使用notebook已经将训练好的model上传到MinIO储存空间, 本篇我们将使用s...

[DAY 24] Dataset 的处理

前言 我们在 Training 的过程的中,一个很重要的 Part 就是如何出一个 Powerful...

Day 16:axios 先封装,API 轻松发

上篇我们在单一元件内使用 axios 发送 API,但如果专案规模愈来愈大,需要同时管理多个功能的 ...