美文网首页
编写可读代码的艺术 - 一次只做一件事

编写可读代码的艺术 - 一次只做一件事

作者: DZQANN | 来源:发表于2022-03-28 21:14 被阅读0次

    将任务分解,一次只做一件事是单一职责的基础,对于代码的服用也会非常有利

    首先书里面举了一个例子,很简单,但是在我们的开发过程中经常会出现

    需求比较简单,给一个"location_info"对象,里面有4个字段,LocalityName、SubAdministrativeAreaName、AdministrativeAreaName、CountryName分别对应城市、大城市、州和国家名。给4个字段的值,生成一个Geo的Display。取值逻辑分两部分,第一部分从前面3个字段里取值,优先取靠前的,比如LocalityName有值就不取SubAdministrativeAreaName。如果3个都没有值就用默认的"Middle-ofNowhere"。第二部分取CountryName,如果为空则取"Planet Earth"

    public String getDisplay(LocationInfo locationInfo) {
      String place = locationInfo.getLocalityName();
      if (!StringUtils.hasLength(place)) {
        place = locationInfo.getSubAdministrativeAreaName();
      }
      if (!StringUtils.hasLength(place)) {
        place = locationInfo.getAdministrativeAreaName();
      }
      if (!StringUtils.hasLength(place)) {
        place = "Middle-of-Nowhere";
      }
      if (StringUtils.hasLength(locationInfo.getCountryName())) {
        place += ", " + locationInfo.getCountryName();
      } else {
        place += ", Plane Earth";
      }
      return place;
    }
    

    对于这段代码,抛开本身说的没有分割任务,我不是很喜欢给一个变量设默认值,然后后面判断不断变化的做法。我更喜欢变量只是短暂的存储一各值,尽量减少变化。

    代码比较简单

    public class Demo {
    
        private static final List<Function<LocationInfo, String>> FIRST_PART_GETTERS = ImmutableList.of(
                LocationInfo::getLocalityName,
                LocationInfo::getSubAdministrativeAreaName,
                LocationInfo::getAdministrativeAreaName
        );
        private static final String DEFAULT_FIRST_PART = "Middle-of-Nowhere";
        private static final String DEFAULT_SECOND_PART = "Plane Earth";
    
        public String getDisplay(LocationInfo locationInfo) {
            return this.getFirstPart(locationInfo) + ", " + this.getSecondPart(locationInfo);
        }
    
        private String getSecondPart(LocationInfo locationInfo) {
            return StringUtils.hasLength(locationInfo.getCountryName()) ?
                    locationInfo.getCountryName() :
                    DEFAULT_SECOND_PART;
        }
    
        private String getFirstPart(LocationInfo locationInfo) {
            return FIRST_PART_GETTERS.stream()
                    .map(e->e.apply(locationInfo))
                    .filter(StringUtils::hasLength)
                    .findFirst()
                    .orElse(DEFAULT_FIRST_PART);
        }
    }
    

    这样做的好处就是把每一个字段的取值都独立开了,方便增加新的需求,而且代码层次比较清晰,如果我只看getDisplay的话,直接就能知道前面一部分拼上逗号再拼后面一部分。每一个字段的取值逻辑如果有变化也方便修改。

    我们的一些接口的塞值逻辑,就是平铺把所有字段的set判断逻辑都写在一个函数里,这样阅读的时候就总有一种被打断的感觉。

    相关文章

      网友评论

          本文标题:编写可读代码的艺术 - 一次只做一件事

          本文链接:https://www.haomeiwen.com/subject/oqubjrtx.html