Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use a mixin for shared behaviour in services
This creates a new mixin, Callable, which can be used to provide a class with the boilerplate so that it can have a public class method of `.call` which calls `#initialize` with the arguments and then `#call`. This mixin replaces the inheritance approach used in services with an ApplicationService class. These classes now all utilise this mixin instead. The reason for doing this was prompted by a linting violation with one of rubocop's newer rules: `Lint/MissingSuper`, which is an offence when a class inherits but does not call `super` in it's initialize method. This violation seemed to only affect some of GOV.UK's newer code, such as this service pattern, which led to some debate [1] about what the most appropriate means to share this behaviour is, whether our inheritance approach was actually idiomatic and how using super in every `initialize` would be unnecessary boilerplate. The Rubocop thread [2] regarding this rule raised an interesting point "I'm curious of examples where there are good reasons to explicitly not call super.", which led to me considering why we didn't think `super` would be appropriate in these classes. My conclusion to this was that we weren't actually intending to create a subtype with inheritance, we actually just wanted standardisation with the interface, and that the inherited classes have very little behavioural consistency, breaking Liskov substitution principle [3]. When looking at the Ruby standard library a module seems the most appropriate way to implement it, considering similarities with modules such as Singleton and Enumerable. Taking inspiration from the Ruby standard library there is an in [1]: alphagov/rubocop-govuk#125 [2]: rubocop/rubocop#8506 [3]: https://thoughtbot.com/blog/back-to-basics-solid#liskov-substitution-principle
- Loading branch information
Showing
23 changed files
with
76 additions
and
28 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# This mixin is to provide the boilerplate for classes that implement a single | ||
# public class method of `.call` - typically used by objects that are entirely | ||
# to perform a business transaction. | ||
module Callable | ||
extend ActiveSupport::Concern | ||
|
||
included do | ||
def self.call(*args, **kwargs, &block) | ||
new(*args, **kwargs, &block).call | ||
end | ||
|
||
private_class_method :new | ||
end | ||
end |