简体   繁体   English

圈复杂度对于方法来说太高了

[英]cyclomatic complexity is too high rubocop for method

This is code I have using in my project.这是我在项目中使用的代码。 Please suggest some optimizations (I have refactored this code a lot but I can't think of any progress further to optimize it )请提出一些优化建议(我已经重构了很多代码,但我想不出进一步优化它的任何进展)

 def convert_uuid_to_emails(user_payload)
    return unless (user_payload[:target] == 'ticket' or user_payload[:target] == 'change')
    action_data = user_payload[:actions]
    action_data.each do |data|
      is_add_project = data[:name] == 'add_fr_project'
      is_task = data[:name] == 'add_fr_task'
      next unless (is_add_project or is_task)
      has_reporter_uuid = is_task && Va::Action::USER_TYPES.exclude?(data[:reporter_uuid])
      user_uuids = data[:user_uuids] || []
      user_uuids << data[:owner_uuid] if Va::Action::USER_TYPES.exclude?(data[:owner_uuid])
      user_uuids << data[:reporter_uuid] if has_reporter_uuid
      users_data = current_account.authorizations.includes(:user).where(uid: user_uuids).each_with_object({}) { |a, o| o[a.uid] = {uuid: a.uid, user_id: a.user.id, user_name: a.user.name} }
      if Va::Action::USER_TYPES.include? data[:owner_uuid]
        data['owner_details'] = {}
      else
        data['owner_details'] = users_data[data[:owner_uuid]]
        users_data.delete(data[:owner_uuid])
      end
      data['reporter_details'] = has_reporter_uuid ? users_data[data[:reporter_uuid]] : {}
      data['user_details'] = users_data.values
    end
  end

Note that Rubocop is complaining that your code is too hard to understand, not that it won't work correctly.请注意,Rubocop 抱怨您的代码太难理解,而不是它无法正常工作。 The method is called convert_uuid_to_emails , but it doesn't just do that:该方法称为convert_uuid_to_emails ,但它不仅仅这样做:

  1. validates payload is one of two types验证有效负载是两种类型之一
  2. filters the items in the payload by two other types按其他两种类型过滤负载中的项目
  3. determines the presence of various user roles in the input确定输入中是否存在各种用户角色
  4. shove all the found user UUIDs into an array将所有找到的用户 UUID 放入一个数组中
  5. convert the UUIDs into users by looking them up通过查找将 UUID 转换为用户
  6. find them again in the array to enrich the various types of user details in the payload在数组中再次查找它们以丰富有效负载中的各种类型的用户详细信息

This comes down to a big violation of the SRP (single responsibility principle), not to mention that it is a method that might surprise the caller with its unexpected list of side effects.这归结为严重违反了 SRP(单一责任原则),更不用说它是一种可能会以其意想不到的副作用列表让调用者感到惊讶的方法。

Obviously, all of these steps still need to be done, just not all in the same method.显然,所有这些步骤仍然需要完成,只是方法不同。

Consider breaking these steps out into separate methods that you can compose into an enrich_payload_data method that works at a higher level of abstraction, keeping the details of how each part works local to each method.考虑将这些步骤分解为单独的方法,您可以将这些方法组合成一个在更高抽象级别上工作的enrich_payload_data方法,将每个部分如何工作的细节保留在每个方法的本地。 I would probably create a method that takes a UUID and converts it to a user, which can be called each time you need to look up a UUID to get the user details, as this doesn't appear to be role-specific.我可能会创建一个接受 UUID 并将其转换为用户的方法,每次您需要查找 UUID 以获取用户详细信息时都可以调用该方法,因为这似乎不是特定于角色的。

The booleans is_task , is_add_project , and has_reporter_uuid are just intermediate variables that clutter up the code, and you probably won't need them if you break it down into smaller methods.布尔值is_taskis_add_projecthas_reporter_uuid只是使代码混乱的中间变量,如果将其分解为更小的方法,您可能不需要它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM