• 【著作阅读笔记】《代码整洁之道》对Sql类的重构引发的思考


    前言

    《代码整洁之道》第十章,类。教我们去识别能支持拓展的代码是怎样的,跟设计模式是有交集的,包括单一原则,开闭原则。借书中的代码和阐述,记录下对原则的认识,及识别高内聚、可拓展的代码。

    旧代码如何违反单一职责的原则

    根据需求要对代码进行修改,是非常合乎软件迭代的。但是如果不同维度的需求,都要对代码进行修改,那么代码就违反了单一职责。先贴原书的代码,后分析。

    /**
     * 修改时违反SPR 原则 (单一职责)
     * Single Responsibility Principle
     * 
     */
    public abstract class Sql {
      //   public Sql(String table, Column[] columns);
      public abstract String create();
    
      public abstract String insert(Object[] fields);
    
      public abstract String selectAll();
    
      public abstract String findByKey(String keyColumn, String keyValue);
    
      public abstract String select(Column column, String pattern);
    
      public abstract String select(Criteria criteria);
    
      public abstract String preparedInsert();
    
      private String selectWithCriteria(String criteria) {
        return "";
      }
    	
      private String columnList(Column[] columns) {
        return "";
      }
    
      private String valuesList(Object[] fields, final Column[] columns) {
        return "";
      }
    
      private String placeholderList(Column[] columns) {
        return "";
      }
    
    • 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

    会产生代码修改的需求变更:

    1. 新增一种新的类型语言,比如加入 update 类型语言
    2. select 支持子查询

    高内聚的要求

    为了方便表达,比如把if (topLevel == 0 && parenet == null) 抽成私有方法 isTop() ,这个是提升代码可读的私有方法。而功能相关的私有方法,只与一部分功能相关,那么很有可能,这个私有方法应该放到其他类中。比如selectWithCriteria 只与 select 语句有关的方法,关心update语句的开发者并不关心前者的代码。

    让代码符合单一职责

    abstract public class Sql {
       public Sql(String table, Column[] columns) {};
       abstract public String generate();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 支持的语句类型的扩展
    class SelectSql extends Sql {
       public SelectSql(String table, Column[] columns) { super(table, columns); }
       
       @Override 
       public String generate() { return ""; }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 对所有语句类型支持条件筛选,提供另外维度的扩展 (不再依赖Sql类),让Sql实现高内聚。selectWithCriteria的语义也能通过下面两个类进行组合。
    class Where {
       public Where(String criteria) {}
       public String generate() { return ""; }
    }
    
    class ColumnList {
       public ColumnList(Column[] columns) {}
       public String generate() { return ""; }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    理解开闭原则

    • 型如下面的拓展模式,我们继承Sql 实现UpdateSql ,对Sql SelectSql 都不需要修改。
    class UpdateSql extends Sql {
       public UpdateSql (String table, Column[] columns) { super(table, columns); }
       
       @Override 
       public String generate() { return ""; }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    我们根据需求拓展了Sql 类,却不用改变Sql 类及其实现类。即对修改关闭,对拓展开放,即开闭原则

    • 此例子还能总结下,单一职责原则可以伴随着开闭原则同时生效,好的代码往往有好的特性,不能把原则都割裂来看
  • 相关阅读:
    五、构造函数《2022 solidity8.+ 版本教程到实战》
    投影仪流明
    ubuntu 系统解决GitHub无法访问问题
    黄仁勋口述:英伟达的发展之道和星辰大海
    C语言水平测试题 过关斩将(3)辗转相除法,前n项求和,整数的正序分解,求最大公约数
    【Java 初阶】----- JDK相关内容
    电脑开机为什么老是要两次?
    Mysql存储json格式数据
    2022年湖北天门中级工程师职称评审要求是什么呢?如何评审呢?甘建二
    PolarDB-X 源码解读:事务的一生
  • 原文地址:https://blog.csdn.net/chenghan_yang/article/details/126212012