Refactor : Extraer una Clase y Metodo
Podemos hacer muchos tipos de Refactor pero hoy nos concentraremos en la extracción de una clase "extract class". Este se refiere al extraer una clase y agrupar los metodos relacionados con esta para terminar con dos clases que definan un poco mejor lo que esta pasando. Aqui les dejo un ejemplo:
class CachedEvent
def self.destroy_all
@db = Mongo::Connection.new('localhost').db("mydb")
coll = @db.collection('cached_events')
coll.remove()
end
def self.destroy(options={})
@db = Mongo::Connection.new('localhost').db("mydb")
coll = @db.collection('cached_events')
coll.remove(options)
end
def self.create(attributes)
## PROBLEM
@db = Mongo::Connection.new("localhost").db("mydb")
coll = @db.collection('cached_events')
coll.insert(attributes)
return coll
end
def self.all
@document = Array.new
@db = Mongo::Connection.new("localhost").db("mydb")
coll = @db.collection('cached_events')
coll.find().each {|doc| @document << doc }
@document
end
def self.last
self.all[-1]
end
end
En el código anterior podemos ver que hay bastante duplicación. Esto es un olor que nos indica que algo esta mal. Recuerden que la duplicación es la causa de muchos problemas en la programación. Pedemos ver que duplicamos la llamada a la conexión a la base de datos, en este caso MongoDB, como tambien duplicamos el llamado a la colección llamada "cached_events".
class MongoC
def self.conection
$mongo_connection ||= Mongo::Connection.new('localhost').db('mydb')
end
end
MongoC.conection
class CachedEvent
def self.collection_name
self.name.underscore.pluralize
end
def self.find_collection
$mongo_connection.collection(collection_name)
end
def self.destroy_all
self.find_collection.remove()
end
def self.destroy(options={})
self.find_collection.remove(options)
end
def self.create(attributes)
self.find_collection.insert(attributes)
end
def self.all
document = Array.new
self.find_collection.find().each {|doc| document << doc }
document
end
def self.last
self.all[-1]
end
end
En este segundo ejemplo podemos ver que el código esta factorizado mucho mejor. Tenemos dos clases. La primera clase se encarga de hacer la llamada de conexión a la base de datos. En la segunda clase podrán ver que realizamos algo parecido al "extract class" pero con el metodo find_collection. Esto lo llamamos "extract method".
Recapitulando podemos decir que:
Una señal para realizar un Refactor es ver parte de nuestro código que son parecidas o identicamente iguales.
Extract Class: es una tecnica en la cual de una clase extraemos otra para separar responsabilidades.
Extract Method: es una tecnica en la cual extraemos un metodos para rehusar en varios metodos dentro de la misma clase.