我想按特定顺序对数组执行多个操作。每个行为单元都有自己的方法,我有这样的东西:
def build_array_of_cool_employees
employees = fetch_all_employees
employees = remove_strange_employees_from employees
employees = add_ideal_employee_to employees
employees = sort_by_awesomeness employees
end
我想知道是否有更好的方法。我觉得我缺少一些可以使我的代码更好的功能。是我吗?
您可以使用可链接的方法创建一个单独的类。像这样:
class EmployeeBuilder
attr_reader :employees
def initialize
@employees = []
end
def fetch_all
@employees.push(:qux, :baz, :bar)
self
end
def remove_strange
@employees.delete(:qux)
self
end
def add_ideal
@employees.push(:foo)
self
end
def sort
@employees.reverse!
self
end
end
并像这样称呼它:
def build_array_of_cool_employees
builder = EmployeeBuilder.new
builder.fetch_all.remove_strange.add_ideal.sort.employees
end
build_array_of_cool_employees
#=> [:foo, :bar, :baz]
在您的情况下,您应该使用方法链接。如果您不想污染Array
类,则可以Array
子类。
class Employees < Array
def self.cool
fetch_all
.remove_strange
.add_ideal
.sort_by_awesomeness
end
def self.fetch_all
new(...)
end
def remove_strange
...
self
end
def add_ideal
...
self
end
def sort_by_awesomeness
...
self
end
end
Employees.cool # => ...
您对方法链接的感觉,这可能读起来稍微好一点,但需要扩展array
,然后您可以按照您认为合适的方式直接在数组上调用自定义方法。更好的办法是让员工列出对象,然后对其进行操作,但想法是相似的。
class Array
def sort_by_awesomeness
#your sort
end
def add_ideal_employee(cool_employee)
self.push(cool_employee)
end
def remove_strange_employees(uncool_employees)
uncool_employees.each do |uncool_employee|
self.delete(uncool_employee)
end
# return self here to continue the method chaining
return self
end
end
def build_array_of_cool_employees
employees = fetch_all_employees.add_ideal_employee(cool_employee).remove_strange_employees(uncool_employees).sort_by_awesomeness
end
这取决于您的方法是如何实现的。如果他们修改了原始数组,您可以执行以下操作:
fetch_all_employees.tap do |employees|
remove_strange_employees_from(employees)
add_ideal_employee_to(employees)
sort_by_awesomeness(employees)
end
请注意,像 delete_if
或 push
这样的方法会修改原始数组,所以如果你在方法的实现中使用它们,它应该可以正常工作。