Loading...
i was looking for some way out to implement abstract factory on ruby code. where i have a VersionControl::ServiceFactory which will take different implementation as factory method. ie. VersionControl::ServiceFactory::subversion, VersionControl::ServiceFactory::git and so on.
though all these “subversion, git, perforce” methods are not predefined, these will be added while new implemention is added. my skeleton (abstract) implementation was in VersionControl::Service, so whatever implemention (svn, git, perforce, other) comes ahead it will implement method from VersionControl::Service method. since ruby doesn’t support class abstraction so this was the only way i got in head.
so my skeleton implemention was consist of the following code in summary -
module VersionControl
# log entry class for data object
class LogEntry; end
# local repository information
class Information; end
# abstract service class.
# define service which will be exposed for a
# normal version controlling service.
class Service
# retrieve recent logs from the current directory
# required parameters - *base project path* and other options.
def logs(p_path, p_options = {}); raise "not implemented method" end
# generate diff from mentioned revision number
# or current revision number
# required parameters - *base project path* and other options.
def diff(p_path, p_options = {}); raise "not implemented method" end
# find repository information
def info(p_path, p_options = {}); raise "not implemented method" end
# check out content from version control server
def checkout(p_source, p_path, p_options = {}); raise "not implemented method" end
end
# factory class for supporting different version control implementation
class ServiceFactory; end
end
and the implementation is written in this way -
class ServiceFactory class < < self # add subversion factory method implementation @@subversion_instance = SubversionService.new def subversion return @@subversion_instance end end end
so every implementation also push it’s factory method to “VersionControl::ServiceFactory” class. so this way i have implemented dynamic abstract factory on ruby.
i was wondering how i could make my test method more organized and DR(Y)ied.
so i had a nice time while i was writing test to ensure my current modification works ok with existing setup.
i don’t know whether any design pattern or best practice is already exist on this topic.
i came up with something that is really good for me. here is a bit about my task and also the explanation about what i did.
i have a model “category” where i have the following relations -
has_many :category_mappings, :dependent => :destroy
has_many :items, :through => :category_mappingshas_many :categories, :foreign_key => “parent_id”, :dependent => :destroy
has_many :attribute_category_mappings, :dependent => :destroy
has_many :properties, :through => :attribute_category_mappingsbelongs_to :category
i was applying :dependent = > :destroy with the mapping model and child categories, which are needs to be removed as a part of the category destroy process.
so i had a messy unit test method to ensure this is working fine. sorry for not keeping my old code snaps otherwise i could show the messy one. anyway here what i wrote later to make it bit cleaner than the previous messy version -
def test_destroy_category_with_dependent
category = Category.find(3)# prepare for verification
prepare_for_verifying_related_property_mappings(category)
prepare_for_verifying_category_mappings(category)
prepare_for_verifying_child_category(category)# perform action
category.destroy# ensure the action
assert_raise(ActiveRecord::RecordNotFound) {
Category.find(category.id)
}# perform verification
verify_related_property_mappings(category)
verify_related_category_mappings(category)
verify_related_child_category(category)
end
here i just sliced my test method in 2 different roles,
1. preparation stage
2. verification stage
1. preparation stage -
in this stage, i just keep log for current state or other steps which are important for later testing.
2. verification stage -
in this stage, i just verified my new state comparing with the old state (which was kept during preparation stage).
so let’s have a look on the typical code which i wrote in my preparation and verification stage -
def verify_related_child_category(p_category)
puts “verify related child categories - #{p_category}”
now_category_count = Category.count
assert_equal(true, ((@old_category_count - now_category_count) > 1),
“No category has been removed.”)
end
this seem pretty good for me, as long as i can make my code bunch simple and easy to change.
best wishes,
at our company (escenic bangladesh), we have some group learning process. learning or grilling design pattern is one of them.
last couple of weeks we had a lot of presentations on lot of design patterns.
today was my turn, i had the presentation on “Delegation pattern”, i have attached my slide with my blog post. hope you will enjoy.







| www.flickr.com |
Leave a reply