不要在 if 条件中使用复杂表达式

H2:关于 Volodymyr Gubarkov 及相关代码

  • 2024 年 8 月,提到一段代码属于某假设应用的通知子系统,用于确定是否向特定用户发送通知。
  • 原始代码:

    if ((((reservationId && notification.reservationId == reservationId)
      || (facilityId && notification.facilityId in facilityId)
      || (hotelIds && hotelIds.contains(notification.hotelId)) && (hotelUser && notification.type.toAllHotelUsers || reservationId && notification.type.toAllReservations))
      || (isAdmin && hotelIds.contains(notification.hotelId))
      && (userId!= notification.authorId || notification.authorId == null))) 
    {
      send(notification)
    }
  • 改进后的代码:

    boolean reservationMatches = reservationId && notification.reservationId == reservationId
    boolean facilityMatches = facilityId && notification.facilityId in facilityId
    boolean hotelMatches = hotelIds && hotelIds.contains(notification.hotelId)
    boolean addressedToAll = hotelUser && notification.type.toAllHotelUsers || reservationId && notification.type.toAllReservations
    boolean shouldSendByHotel = hotelMatches && (addressedToAll || isAdmin)
    boolean senderIsNotReceiver = userId!= notification.authorId || notification.authorId == null
    boolean notificationMatchesUser = senderIsNotReceiver && (reservationMatches || facilityMatches || shouldSendByHotel)
    
    if (notificationMatchesUser) {
      send(notification)
    }
  • 改进思路:将复杂表达式拆分为有意义的子表达式,使代码更易维护和理解。原始代码难以判断条件是否符合业务需求,而改进后可清晰看出通知仅在符合用户条件(业务需求)时发送,即发送者不是接收者且预订或设施匹配或受酒店支持等。
  • 重写代码的好处:每次给某个部分命名都有机会思考名称是否准确,能发现潜在错误,且调试更易,当if条件错误时,可设置断点查看子表达式实际值,容易找出错误子表达式。
  • 提示:一般不应在if条件中使用||&&,但在简单情况下可以。以下两种方式同样良好:

    if (notificationMatchesUser(notification, reservationId, facilityId, hotelIds, userId)) {
      send(notification)
    }
    if (notification.matches(reservationId, facilityId, hotelIds, userId)) {
      send(notification)
    }
  • 最后提醒如有拼写错误或其他反馈可发邮件至 mailto:xonixx@gmail.com
阅读 14
0 条评论