Last active
August 29, 2015 13:56
-
-
Save kostia/9254184 to your computer and use it in GitHub Desktop.
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
# Bad, because declarative code without business logic should NOT be absolutely DRY. | |
%w[Bob Alice].each do |first_name| | |
%w[Black White].each do |second_name| | |
Person.create(first_name: first_name, second_name: second_name) | |
end | |
end | |
# Good, because it's clear, what results the code produces. Declarative, baby! | |
# Not perfect, because the naming of the params is | |
# "kind of business logic" in some situations. | |
Person.create first_name: 'Bob', second_name: 'Black' | |
Person.create first_name: 'Alice', second_name: 'Black' | |
Person.create first_name: 'Bob', second_name: 'White' | |
Person.create first_name: 'Alice', second_name: 'White' | |
# Better, but a matter of taste. | |
def create_person(first_name, second_name) | |
Person.create first_name: first_name, second_name: second_name | |
end | |
create_person 'Bob', 'Black' | |
create_person 'Alice', 'Black' | |
create_person 'Bob', 'White' | |
create_person 'Alice', 'White' | |
# Bad. The code is not declarative anymore, because it contains business logic. | |
# Often one can recognize the business logic by it's non-linear control flow. | |
# Business logic must be DRY. | |
unless Person.exists?(first_name: 'Bob', second_name: 'Black') | |
Person.create(first_name: 'Bob', second_name: 'Black') | |
end | |
unless Person.exists?(first_name: 'Alice', second_name: 'Black') | |
Person.create(first_name: 'Alice', second_name: 'Black') | |
end | |
unless Person.exists?(first_name: 'Bob', second_name: 'White') | |
Person.create(first_name: 'Bob', second_name: 'White') | |
end | |
unless Person.exists?(first_name: 'Alice', second_name: 'White') | |
Person.create(first_name: 'Alice', second_name: 'White') | |
end | |
# Good, because the non-declarative logic (business logic) | |
# has been extracted into a DSL method, which now can be used declaratively. | |
def create_person_unless_exists(first_name, second_name) | |
attributes = {first_name: first_name, second_name: second_name} | |
Person.create(attributes) unless Person.exists?(attributes) | |
end | |
create_person_unless_exists 'Bob', 'Black' | |
create_person_unless_exists 'Alice', 'Black' | |
create_person_unless_exists 'Bob', 'White' | |
create_person_unless_exists 'Alice', 'White' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment