Ruby - Et si on écrivait un ORM ? - partie 9
Encore du refactoring, cette fois ci dans la classe Base. Regardons le
code suivant:
class Base
def self.sql(raw_query)
Database.connection.execute(raw_query)
endLe Database.connection.execute me dérange. Il viole
la loi de Demeter.
À bien y réfléchir, je n’ai tout simplement pas envie d’exposer la méthode
connection, qu’on trouve aussi un peu plus loin dans la class Base:
def self.save(parameters)
Recorder.new(Database.connection, self.to_s.downcase, parameters).save
self.new(parameters)
endLa classe Database est actuellement comme ça:
class Database
@@connection = false
def self.connect(database_filename)
@@connection = SQLite3::Database.open(database_filename)
end
def self.connected?
!!@@connection
end
def self.connection
@@connection
end
endJe supprime purement et simplement la méthode connection:
class Database
@@connection = false
def self.connect(database_filename)
@@connection = SQLite3::Database.open(database_filename)
end
def self.connected?
!!@@connection
end
endMaintenant, on rejoue les tests, qui vont nous indiquer ce qui doit être réécrit:
$ rspec sorm_spec.rb
[...]
NoMethodError:
undefined method `connection' for SORM::Database:Class
# ./sorm.rb:19:in `sql'
[...]
NoMethodError:
undefined method `connection' for SORM::Database:Class
# ./sorm.rb:23:in `save'
[...]
7 examples, 5 failures
On va simplement créer une méthode Database.execute, qui elle, pourra
utiliser l’objet connection:
class Database
@@connection = false
def self.connect(database_filename)
@@connection = SQLite3::Database.open(database_filename)
end
def self.connected?
!!@@connection
end
def self.execute(sql)
@@connection.execute(sql)
end
end
class Base
def self.sql(raw_query)
Database.execute(raw_query)
end
# ...À y regarder de près, je ne suis plus certain de trouver un intérêt à
Base.sql. Il faudrait la supprimer puisqu’elle peut être remplacée par
Database.execute. Mais il faudra attendre car il y a encore des tests qui ne
passent plus, à cause de ce code:
def self.save(parameters)
Recorder.new(Database.connection, self.to_s.downcase, parameters).save
self.new(parameters)
endOn s’en occupera la prochaine fois.
To be continued
À demain.