i'm trying implement facade in idiomatic ruby while coming java. can see rails' activerecord
fond of using class methods things find_by(criteria)
, not use repository pattern task.
my facade wraps specific webservice several methods. original idea make it's api similar activerecord
(learning imitation):
class myentity # .... def get_name @loaded_name + @loaded_surname end def delete @entity_access_service.delete(@id) end def save @entity_access_service.save(@id, @loaded_name , @loaded_surname) end def self.find(id) data = @entity_access_service.get_data_for(id) myentity.new(data) #or whatever way populate entity end end
this, in theory, work great:
e = myentity.find(10) p e.get_name e.delete
or:
e = myentity.new(some stuff) e.save
question: save
, delete
instance methods work, need somehow instance of entityaccessservice
. instance should mockable test in isolated environment. correct way it?
i'm expecting tests simple possible , without weird hacks, i'm trying implement seems trivial.
i have thought of several options that:
having class-level variable holding
entity_access_service
used of entities created in application. in case, should initialize field? example:class myentity @@entity_access_service = nil end # somewhere else (where?): myentity.entity_access_service = myentityservice.new(some_params_from_env)
this way, in tests have initialize/mock @ start.
similar 1 initialize in class. looks weird, if know tests not have required env params populated @ all.
have constructor/attribute set
entity_service
. won't work,save
not have field initialized.create
repository
class. work pretty ok, seems not ruby people do.
following activerecord's example, can create method on class itself, or on base class other classes derived.
activerecord provides method activerecord::base.connection
returns connection object models use access database. can similar:
class myentity .... def self.entity_access_service # return service object end def self.find(id) myentity.entity_access_service.get_data_for(id) myentity.new(data) # or whatever way populate entity end def save() myentity.entity_access_service.save(@id, @loadedname, @loadedsurname) end end
as far initialization goes, either have have initialization step in app (and test suite) service credentials read config files , passed myentity
object, or entity_access_service
method can lazily create object returns on first access using common ruby idiom:
def self.entity_access_service @entity_access_service || = # build entity_access_service object end
note that, wrapping class-level instance variables in class-level accessor methods, can avoid use of @@
recommended best practice.
Comments
Post a Comment