维护代码比编写代码更复杂。 在进行任何更改之前,您需要了解已有的内容、它应该如何工作以及它现在如何工作。 这项任务的难度取决于代码的结构以及代码是否易于阅读。 在本文中,我将向您展示如何使代码更具可读性,从而更易于维护。
切入点当您在应用程序上启动票证时,通常您会获得一些有关应在何处进行更改或修复的信息。 如果您始终使用某种约定来命名和放置文件,则可以更轻松地将该位置链接到代码。 让我们看几个例子。
基于组件的应用程序在我的日常工作中,我构建和维护一些使用组件构建的 Angular 应用程序。 每个应用程序都定义了许多路由,并且对于每个路由,都有一个负责此视图的顶级组件。 我们使用的命名约定如下:
简单路由:/home-page—<home-page>
嵌套路由:/long/nested-route—<long-nested-route>
带参数的路由:/user/:id/edit—<user-edit>
这样,如果我得到了应该发生更改的路径,我可以立即找到相关的组件文件。
后端
在后端,我们对使用的路由施加了一些限制。 该 API 大致受到 REST 方法的启发,每个端点都与我们数据库中的集合之一相关。 路由的格式为 /collection/operation,例如:
/用户/获取
/交易/获取报告
这些端点调用的代码按集合组织在文件中:因此在一个文件中我们有与用户集合相关的方法,在另一个文件中我们有与事务相关的方法。 这样,根据API路线的第一部分,我就知道去哪里寻找代码了。
避免不必要的跳跃我经常看到的使代码变得复杂的方法之一是让读者经历许多不必要的跳转。 当你阅读代码时,不可避免地需要在不同部分之间进行一些跳转。 当跳转很多且不必要时,这就会成为一个问题。 一些基于我在现实世界代码中看到的示例:
除了为另一个函数创建别名之外不执行任何操作的函数
function A(param1, param2) { return B(param1, param2)}
这对于一些重构来说是有意义的,但最好在临时情况下使用它,
命名回调函数的定义远离它们的使用位置:
function success() { /*..success..*/}function error() { /*..error..*/}getPromise().then(success, error)
如果是这样的话,同样的事情会更容易阅读:
getPromise().then(() => { /*..success..*/}, () => { /*..error..*/})变量中测试集的期望,远离它们的使用位置:
const expectedObject = { /*.me big object..*/ };/*..many lines of code..*/expect(result).toEqual(expectedObject);
每当我们在代码中发生跳转时,我们都会使其阅读起来稍微复杂一些。 让我们确保这种不便可以通过某种好处来平衡——有充分的理由这样做。
把事情简单化您的代码流程应该是直接的。 应该很容易绘制一个图表来说明逻辑如何流经应用程序以及事物如何相互依赖。 代码中不应该有循环路径,除非您有意进行一些递归。
您的目标应该是始终能够解释用户操作或某些外部事件如何导致数据更改。 如果您无法轻易分辨出什么负责什么,那么您的代码很可能是混乱且难以遵循的。
显示数据最简单的情况是转换数据以供显示。 这可能是许多事情之一:
在用户的区域设置中格式化日期,
翻译成用户的语言,
将一个对象的许多属性合并为一个,准备显示字符串,或者
根据搜索过滤数组。
这些操作中的每一个都应该具有易于识别的输入和输出格式,并且应该以读者知道什么输入和输出的形式编写。
格式化数据以供显示时应保持原始数据不变——没有理由仅仅因为数据显示在某个位置就更改数据。
改变状态当您更改数据状态时,应该可以轻松识别代码的以下部分:
更改的来源——单击的按钮、系统中发生的事件等。
更改本身 - 检查约束并更新数据状态的代码
将更改保存到存储 - 对于后端代码,这可能是对数据库的更新,或者对于前端代码,这可能是调用保存 API
如果由于某种原因,您不容易确定代码的哪些部分负责其中的某些点,那么阅读此代码可能会非常混乱。
可测试性我们在这里讨论的所有内容都与编写可测试代码一致。 具有明确职责的小型、定义明确的单元易于开发人员理解,并且易于测试。 对我来说,编写测试是一个很好的练习,它可以教你编写更具可读性的代码:只需注意何时测试开始变得痛苦以及何时代码变得过于复杂而难以轻松使用。
/kill @e[type = evocation_illager] 清除卫道士
/gamemode 0 生存
/gamemode 1 创造
/gamemode 2 冒险
/gamemode 3 旁观 (旧版本不能使用)
/gamerule keepInventory true 死亡不掉落指令
/difficulty 0,1,2,3 分别是和平,简单,普通,困难
/give 玩家名 物品ID 物品数量 给予玩家物品
/weather rain 下雨
/weather clear 无天气
/weather thunder 雷阵雨
/kill 自杀
/spawnpoint 设置重生点
/effect clear 移除身上所有效果
/clear 清除背包所有物品
/scoreboard 计分板
/advancement 更改玩家进度
,/bossbar 更改boss血条
,/clear 清除玩家物品
,/clone 复制方块,
/data 改变方块或实体的NBT数据,
/datapack 管理数据包,
/debug 开始调试,
/defaultgamemode 更改默认游戏模式
/difficulty 设置难度,
/effect 添加或移除药水效果,
/enchant 附魔玩家物品,
/execute 以另一实体身份执行命令,
/experience 刷经验,
/fill 填充方块,
/function 运行函数,
/gamemode 更改游戏模式,
/gamerule 更改游戏规则,
/give 给玩家物品,
/help 显示帮助,
/kill 杀死实体,
/locate 定位最近的建筑坐标,
/me (不知道如何描述),
/particle 生成粒子效果,
/playsound 播放音乐,
/recipe 管理合成,
/reload 重载数据包,
/replaceitem 替换物品
/say 说话,
/scoreboard 记分板,
/seed 显示种子,
/setblock 放置方块,
/setworldspawn 设置出生点
/spawnpoint 设置重生点,
/spreadplayers 随机分散实体,
/stats 探测命令执行结果,
/stopsound 停止音效,
/summon 生成实体,
/tag 修改实体标签,
/team 修改队伍,
/teleport 传送实体(和tp有点区别),
/tell 发私信,
/tellraw 发送高级信息,
/testfor 探测实体
/testforblock 探测方块,
/testforblocks 探测区域内方块是否相同,
/time 更改或查询时间,
/title 显示标题,
/toggledownfall 切换天气,
/tp 传送实体,
/trigger 更改判据为trigger的计分板,
/weather 设置天气,
/worldborder 更改世界边缘,
/xp 刷经验.
/?/help的替代命令,提供命令使用帮助
/ability赋予或剥夺玩家的能力。
/clear从玩家物品栏中删除物品。
/clone将特定区域的方块复制到另一处。
/connect/wsserver的替代命令,连接至WebSocket服务器。
/deop撤销玩家的管理员权限。
/difficulty设置难度等级。
/effect添加或移除状态效果。
/enchant附魔玩家的物品。
/execute执行另一命令。
/experience给予玩家经验。
/fill将某个区域填满特定方块。
/function运行一个函数。
/gamemode更改玩家的游戏模式。
/gamerule更改或查询游戏规则值。
/give给予玩家物品。
/help提供命令使用帮助。
/kill杀死实体(玩家、生物、物品等)。
/list列出服务器中的玩家。
/locate显示最近给定结构的坐标。
/me显示一条关于自己的信息。
/mixerMixer交互性控制。
/mobevent控制或查询允许运行的生物事件。
/msg/tell的替代命令,向另一玩家发送私信。
/op授予玩家管理员权限。
/particle创建颗粒。
/playsound播放音效。
/reload从硬盘中重新加载战利品表、进度和函数。
/replaceitem替换物品栏中的物品。
/resupply立即补给村庄新经济供需体系。
/save准备备份,查询其状态或恢复。
/say向多个玩家发送消息。
/scoreboard管理记分板目标、玩家、队伍与标签。
/setblock将方块替换为其他方块。
/setmaxplayers设置可加入游戏的玩家数量上限。
/setworldspawn设置世界出生点。
/spawnpoint为玩家设置出生点。
/spreadplayers将实体传送到随机位置。
/stopsound 停止音效。
/summon 生成实体。
/tag 修改玩家或实体的标签。
/teleport /tp的替代命令,传送实体。
/tell 向另一玩家发送私信。
/tellraw向玩家显示JSON消息。
/testfor 统计符合给定条件的实体。
/testforblock测定某方块是否在某位置。
/testforblocks 测定两个区域中的方块是否相同。
/time 更改或查询游戏中的世界时间。
/title 管理屏幕上的标题。
/toggledownfall 切换天气。
/tp 传送实体。
/w /tell的替代命令,向另一玩家发送私信。
/weather设置天气。
/wsserver 连接至WebSocket服务器。
/xp 增加或减少经验。
召唤生物:召唤已驯服的僵尸马:/summon EntityHorse ~ ~ ~ {Type:3,Tame:1}
召唤未驯服的僵尸马:/summon EntityHorse ~ ~ ~ {Type:3}
召唤已驯服的骷髅马:/summon EntityHorse ~ ~ ~ {Type:4,Tame:1}
召唤未驯服的骷髅马:/summon EntityHorse ~ ~ ~ {Type:4}
召唤僵尸巨人:/summon Giant
/summon Giant 巨型僵尸
/summon EnderDragon 末影龙
/summon WitherBoss 凋零
/summon Skeleton 骷髅
/summon Pig ~ ~ ~ 输入指令可以刷出一只猪
/summon Cow ~ ~ ~ 输入指令可以刷出一只牛
/summon Zombie ~ ~ ~ 输入指令可以刷出一只僵尸
/summon Cow - 牛
/summon Chicken - 鸡
/summon MushroomCow - 蘑菇牛
/summon Bat - 蝙蝠
/summon Pig - 猪
/summon EntityHorse - 马
/summon Sheep - 羊
/summon Villager - 村民
/summon VillagerGolem - 铁傀儡
/summon SnowMan - 雪傀儡
/summon Wolf - 狼/狗
/summon Ozelot - 猫
/summon Squid - 鱿鱼
/summon Zombie - 僵尸
/summon Skeleton - 骷髅
/summon Creeper - 苦力怕/自爆怪/JJ怪
/summon PigZombie - 僵尸猪人
/summon Ghast - 幽灵/恶魂
/summon Enderman - 末影人/“黑基佬”
/summon Silverfish - 银鱼虫/螨虫
/summon Endermite - 末影螨虫
/summon Slime - 史莱姆
/summon LavaSlime - 地狱史莱姆
/summon Witch - 女巫
/summon Guardian - 水下保卫
/summon Blaze - 烈焰人
/summon Spider - 蜘蛛
/summon CaveSpider - 洞穴蜘蛛
/summon EnderDragon - 末影龙Boss
/summon WitherBoss - 凋零Boss
/summon Giant - 巨型僵尸
非生物:
/summon Boat - 船
/summon MinecartRideable - 普通矿车
/summon MinecartHopper - 漏斗矿车
/summon MinecartFurnace - 熔炉矿车
/summon MinecartCommandBlock - 指令方块矿车
/summon MinecartChest - 箱子矿车
/summon MinecartSpawner - 刷怪笼矿车
/summon SmallFireball - 小型火球(烈焰人发出的)
/summon Fireball - 火球(恶魂发出的)
/summon Item - 物品
/summon LeashKnot - 绳子结
/summon Painting - 画
/summon LightningBolt - 雷电
/summon ThrownExpBottle - 已扔出的XP瓶子
/summon WitherSkull - 凋零骷髅头(凋零Boss发出的骷髅头)
/summon EnderCrystal - 末影水晶
/summon FireworksRocketEntity - 已发出的烟火
/summon Arrow - 已射出的箭
/summon ThrownPotion - 已扔出的药
ThrownEnderpearl - 已扔出的末影珍珠
/summon EyeOfEnderSignal - 末影之眼的信号
/summon PrimedTnt - 已点燃的TNT
/summon FallingSand - 掉落沙属性
/summon ItemFrame - 物品显示
/summon XPOrb - 经验球
/summon unknown - 鱼饵