Abbiamo un oggetto con backup persistente e ha un campo version
nel database. Supponiamo che ci sia un sacco di codice non correlato in questo
Classe.
#
# We're branching on this "version" field, and we return one
# of 2 policies.
#
class Foo
def policy
if version == 'a'
PolicyA.new
else
PolicyB.new
end
end
end
#
# PolicyA calls a single check on a collaborator.
#
class PolicyA
def pass?(collaborator)
collaborator.check_x?
end
end
#
# PolicyB calls two different checks.
#
class PolicyB
def pass?(collaborator)
collaborator.check_x? && collaborator.check_y?
end
end
#
# One day, we need a 3rd policy version.
#
class Foo
def policy
if version == 'a'
PolicyA.new
elsif version == 'b'
PolicyB.new
else
PolicyC.new
end
end
end
#
# PolicyC needs 2 collaborators, so we add a second argument
# and assign a default.
#
class PolicyA
def pass?(collaborator_a, _collaborator_b = nil)
collaborator_a.check_x?
end
end
#
# Same here.
#
class PolicyB
def pass?(collaborator_a, _collaborator_b = nil)
collaborator_a.check_x? && collaborator_a.check_y?
end
end
#
# Here we pass in a second collaborator and query it.
#
class PolicyC
def pass?(collaborator_a, collaborator_b)
collaborator_a.check_y? && collaborator_b.check_z?
end
end
#
# Some code has to use this thing.
#
class PolicyChecker
def check(foo)
foo.policy.pass?(collaborator_a, collaborator_b)
end
end
C'è una buona via d'uscita che non comporta sottoclasse Foo?
Che ne pensi di trattare con questi collaboratori? Cosa succede quando un terzo arriva?
Raggiungere foo
per arrivare a policy
sembra sbagliato, ma policy
anche conoscere foo.version
è sbagliato.
Qual'è un buon percorso da qui?