Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concerns vs Services

Recently I was building a complex logic controller and wanted to refactor it due to “Single responsibility” principle. So I read about Services. But sometimes later I saw concerns. I though that it’s a replacement for Services in ruby (since there is no default Services folder and etc.), but couldn’t find any good article like “concerns vs services” or etc.

Than I heard that concerns is for model and services for controller, but still, can’t find any topic or article that are proving this.

Can anybody explain the difference of services and concerns and when to use them?

like image 313
Src Avatar asked Sep 27 '17 21:09

Src


2 Answers

Concerns and services are very different abstraction patterns used for entirely different purposes.

  • Services are operations/functions turned into classes.
  • Concerns are mixins.

Say I want to authenticate a user. I could easily just write a authenticate(username, password) function, but it might be useful to encapsulate the logic for that function in a class instead:

class AuthenticationService
  def initialize(username, password); end
  def run(); end
end

Aside from helping me encapsulate all of the logic for authentication in a single class, this allows me to create other authentication classes.

class GoogleAuthenticationService
  def initialize(username, password); end
  def run(); end
end

class FacebookAuthenticationService
  def initialize(username, password); end
  def run(); end
end

A concern, on the other hand, mixes functionality from a module into another class. Say you have a Rails controller that was concerned with authorizing a user. You might write a concern that implements a before_action which checks to see if the user is authorized. Then you could mix that concern into any controller where you wanted to enforce that authorization check.

like image 136
fny Avatar answered Sep 21 '22 08:09

fny


Concerns are essentially modules that allow you to encapsulate aspects of models into separate files to DRY up your code. The advantage is that they inherit from the ActiveSupport:Concern module, so you can access the ActiveRecord operations like validations and associations for the model in which the concern is included.

Service objects are used primarily to wrap a method in an object. These are useful in splitting logic up into small reusable components. These are often used for decoupling systems, and making systems easier to understand, because fundamentally what they do take you from a few many-purpose classes to many classes with a single purpose.

I have my concerns about concerns and tend to err on the side of caution with them.

Fny's answer has just shown up for me whilst writing and I think should be the accepted answer :)

like image 42
Stuart Avatar answered Sep 19 '22 08:09

Stuart