如何将generateKeyList方法的认知复杂度从26降至15?
降低认知复杂度的优化思路
1. 拆分嵌套逻辑为独立小方法
把循环内的子逻辑抽成单一职责的小方法,减少嵌套层次,让每个方法的逻辑更聚焦,可读性大幅提升:
private void generateKeyList(String pdm, List<Key> uKs, List<PhysicalKey> pKs) { if (pKs == null && uKs == null) return; JsonObject concepts = getConcepts(pdm); String indexTypeRequired = uKs == null ? "PRIMARY-KEY" : "UNIQUE"; for (String concept : concepts.keySet()) { processConcept(concepts.getAsJsonObject(concept), concept, indexTypeRequired, uKs, pKs); } } private void processConcept(JsonObject conceptObj, String tableName, String indexTypeRequired, List<Key> uKs, List<PhysicalKey> pKs) { JsonArray indexes = conceptObj.getAsJsonArray("indexes"); if (indexes == null) return; for (JsonElement indexElement : indexes) { processIndex(indexElement, tableName, indexTypeRequired, uKs, pKs); } } private void processIndex(JsonElement indexElement, String tableName, String indexTypeRequired, List<Key> uKs, List<PhysicalKey> pKs) { JsonObject indexO = indexElement.getAsJsonObject(); String indexType = indexO.getAsJsonPrimitive("indexType").getAsString(); if (!indexType.equals(indexTypeRequired)) return; String name = indexO.getAsJsonPrimitive("name").getAsString(); JsonArray keys = indexO.getAsJsonArray("key"); for (JsonElement indexKey : keys) { createAndAddKey(indexKey.getAsString(), name, indexType, tableName, uKs, pKs); } } private void createAndAddKey(String column, String keyName, String indexType, String tableName, List<Key> uKs, List<PhysicalKey> pKs) { if (uKs != null) { uKs.add(new Key().setName(keyName).setType(indexType).setTable(tableName).setColumn(column)); } else { pKs.add(new PhysicalKey().setName(keyName).setType(indexType).setTable(tableName).setColumn(column)); } }
2. 使用Stream API扁平化嵌套循环
Stream的链式调用可以替代多层嵌套循环,把嵌套结构转化为线性的逻辑流,降低认知负担:
private void generateKeyList(String pdm, List<Key> uKs, List<PhysicalKey> pKs) { if (pKs == null && uKs == null) return; JsonObject concepts = getConcepts(pdm); String indexTypeRequired = uKs == null ? "PRIMARY-KEY" : "UNIQUE"; concepts.entrySet().stream() // 提取表名和对应的索引数组 .map(entry -> Map.entry(entry.getKey(), entry.getValue().getAsJsonObject().getAsJsonArray("indexes"))) // 过滤掉无索引的表 .filter(entry -> entry.getValue() != null) // 展开索引元素,关联表名 .flatMap(entry -> entry.getValue().stream() .map(indexElement -> Map.entry(entry.getKey(), indexElement.getAsJsonObject())) // 过滤出目标类型的索引 .filter(indexEntry -> indexEntry.getValue().getAsJsonPrimitive("indexType").getAsString().equals(indexTypeRequired))) // 处理符合条件的索引 .forEach(indexEntry -> { String tableName = indexEntry.getKey(); JsonObject indexO = indexEntry.getValue(); String name = indexO.getAsJsonPrimitive("name").getAsString(); String indexType = indexO.getAsJsonPrimitive("indexType").getAsString(); // 处理索引下的每一列 indexO.getAsJsonArray("key").stream() .map(JsonElement::getAsString) .forEach(column -> { if (uKs != null) { uKs.add(new Key().setName(name).setType(indexType).setTable(tableName).setColumn(column)); } else { pKs.add(new PhysicalKey().setName(name).setType(indexType).setTable(tableName).setColumn(column)); } }); }); }
3. 提前终止无效分支,减少嵌套层级
在循环内尽早判断无效条件并跳过/返回,避免不必要的代码嵌套。比如在处理索引时,先判断索引类型是否匹配,不匹配直接终止当前循环迭代,不用执行后续逻辑。
4. 消除重复的null检查逻辑
原代码中多次重复判断uKs == null,可以用一个变量提前存储判断结果,减少重复的条件分支:
private void generateKeyList(String pdm, List<Key> uKs, List<PhysicalKey> pKs) { if (pKs == null && uKs == null) return; boolean isPrimaryKey = uKs == null; String indexTypeRequired = isPrimaryKey ? "PRIMARY-KEY" : "UNIQUE"; JsonObject concepts = getConcepts(pdm); for (String concept : concepts.keySet()) { JsonArray indexes = concepts.getAsJsonObject(concept).getAsJsonArray("indexes"); if (indexes == null) continue; for (JsonElement index : indexes) { JsonObject indexO = index.getAsJsonObject(); String indexType = indexO.getAsJsonPrimitive("indexType").getAsString(); if (!indexType.equals(indexTypeRequired)) continue; String name = indexO.getAsJsonPrimitive("name").getAsString(); JsonArray keys = indexO.getAsJsonArray("key"); for (JsonElement indexKey : keys) { String column = indexKey.getAsString(); if (isPrimaryKey) { pKs.add(new PhysicalKey().setName(name).setType(indexType).setTable(concept).setColumn(column)); } else { uKs.add(new Key().setName(name).setType(indexType).setTable(concept).setColumn(column)); } } } } }
5. 移除不必要的强制类型转换
原代码中(PhysicalKey) key的强制转换可以通过提前判断集合类型,直接创建对应类型的对象来避免,既提升代码安全性,也减少了复杂度。
内容的提问来源于stack exchange,提问作者pensee
相关产品推荐
相关产品推荐

