Last active
August 29, 2015 13:57
-
-
Save Integralist/9910271 to your computer and use it in GitHub Desktop.
Refactoring Ruby -> not all conditionals can be removed, and those that can can't necessarily use the standard refactoring methods such as "Replace Type Code with Module Extension", "Replace Type Code with Polymorphism" or "Replace Type Code with State/Strategy". The below examples demonstrate this.
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
class Foo | |
def initialize(a=[], b=[]) | |
@a = a | |
@b = b | |
end | |
def add(item) | |
if item.is_a? A | |
@a.push item | |
else | |
@b.push item | |
end | |
end | |
end | |
class A | |
def initialize(name="Unknown") | |
@name = "A: #{name}" | |
@time = Time.now | |
end | |
end | |
class B | |
def initialize(name="Unknown") | |
@name = "B: #{name}" | |
@time = Time.now | |
end | |
end | |
foo = Foo.new | |
foo.add(A.new) | |
foo.add(B.new) |
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
# Thanks to @clauswitt for his guidance | |
class Foo | |
def initialize(storage={}) | |
@storage = storage | |
end | |
def add(item) | |
@storage[item.class] = [] unless @storage.has_key?(item.class) | |
@storage[item.class] << item | |
end | |
end | |
class A | |
def initialize(name="Unknown") | |
@name = "A: #{name}" | |
@time = Time.now | |
end | |
end | |
class B | |
def initialize(name="Unknown") | |
@name = "B: #{name}" | |
@time = Time.now | |
end | |
end | |
foo = Foo.new | |
foo.add(A.new) | |
foo.add(B.new) |
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
# - I've assumed you've separated the items into two arrays | |
# because you want to select those items at some point later. | |
# I've refactored to 'filter' the items on the way out, rather | |
# than filtering them on the way in. | |
# - Also added a :type method rather than class checking. | |
# - You could even use Set instead of [] here | |
class Foo | |
def initialize(initial_items = []) | |
@items = initial_items | |
end | |
def add(item) | |
@items << item | |
end | |
def a | |
select(:a) | |
end | |
def b | |
select(:b) | |
end | |
private | |
def select(type) | |
@items.select { |item| item.type == type } | |
end | |
end | |
# If you wanted to create more types in the future, say :c, you | |
# could dynamically generate the accessors? | |
class A | |
def initialize(name="Unknown") | |
@name = "A: #{name}" | |
@time = Time.now | |
end | |
def type | |
:a | |
end | |
end | |
class B | |
def initialize(name="Unknown") | |
@name = "B: #{name}" | |
@time = Time.now | |
end | |
def type | |
:b | |
end | |
end | |
foo = Foo.new | |
foo.add(A.new) | |
foo.add(B.new) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
of the top of my head:
class Foo
def initialize(storage={})
@storage = storage
end
def add(item)
@storage[item.class] = [] unless @storage.has_key?(item.class)
@storage[item.class] << item
end
end