When writing a program, I think that you may cut out general-purpose functions into classes and methods and implement them.
For example, consider the process of having multiple specified users participate in a specific event.
First, check the implementation when all the processing is in one method. (I wrote it in Ruby, but if you have done other programming languages, you can get a feel for it.)
def main(user_ids, event_id)
users = User.where(id: user_ids)
event = Event.find(event_id)
#Excludes participating users
target_users = users.reject {|user| user.events.ids.include?(event.id) }
#Participation in the event
target_users.each do |user|
#Participation in the event=>Add record to EventUser
EventUser.create!(user: user, event: event)
end
end
Let's cut out the event participation process as a method from the above. This time I added a method to the Event model.
def main(user_ids, event_id)
users = User.where(id: user_ids)
event = Event.find(event_id)
#Excludes participating users
target_users = users.reject {|user| user.events.ids.include?(event.id) }
#Participation in the event
event.join(target_users)
end
app/models/event.rb
def join(users)
users.each do |user|
#Participation in the event=>Add record to EventUser
EventUser.create!(user: user, event: event)
end
end
Now, if you want to execute the process of joining an event from somewhere else, you can call it with ʻevent.join (users)`.
However, this implementation method has some subtleties. That is, the caller must pass only the users who can participate, excluding the users who have already joined.
In the case of this example, it will be easier for the caller to do the following.
def main(user_ids, event_id)
users = User.where(id: user_ids)
event = Event.find(event_id)
#Participation in the event
#The caller doesn't have to worry if users have already joined. OK if you pass the user who can be the target
event.join(users)
end
app/models/event.rb
def join(users)
#Excludes participating users
target_users = users.reject {|user| user.events.ids.include?(event.id) }
target_users.each do |user|
#Participation in the event=>Add record to EventUser
EventUser.create!(user: user, event: event)
end
end
If implemented in this way, the caller can pass the target user without worrying about whether it has joined or not.
If you explain in order like this time, it may seem natural to implement the third one, but in reality, you often see the one implemented in the second state.
This is because there is no sense of discomfort even if the method alone is said to be "a method that allows users to participate in events." The second generalized part is reprinted below. How about looking at this method alone?
app/models/event.rb
def join(users)
users.each do |user|
#Participation in the event=>Add record to EventUser
EventUser.create!(user: user, event: event)
end
end
Also, when you first create a generic method, you may have few (or only one) callers. In that case, it doesn't take much time to check at the caller or at the callee, so it's hard to feel the hassle of having to check everything at the caller.
And once implemented like this, when implementing the process of participating in the event in the same way, the existing part will be copied. In that case, the mechanics of "Because the existing one is like this" will work, and it will be taken for granted rather than annoying.
When implementing a general-purpose function, is it easy for the user to use? Let's be aware of. If the user has to consider various restrictions or there are processes that must be executed (processes excluding participants in this example), those processes can be incorporated into general-purpose functions. Let's consider whether it is possible.
Doing so will not only make it easier for users, but will also prevent bugs such as implementation omissions.
Also, if you want to make it for general purposes, it will be used. If it is difficult to use, there is a high possibility that only the person who implemented it can use it (the person who implemented it may not be able to use it after a few months) Let's keep in mind the implementation that is easy for users to use and enjoy! !!
Recommended Posts