Loading... Cancel

ruby dynamic abstract factory implementation R

May 10th, 2008

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.

split out test case into “preparation” and “verification” state. R

October 28th, 2007

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_mappings

has_many :categories, :foreign_key => “parent_id”, :dependent => :destroy

has_many :attribute_category_mappings, :dependent => :destroy
has_many :properties, :through => :attribute_category_mappings

belongs_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 prepare_for_verifying_child_category(p_category)
puts “Prepare for verifying related child category - #{p_category}.”
@old_category_count = Category.count
@old_child_category_count = p_category.categories.count
@old_child_categories = Category.find_all_by_parent_id(p_category.id)
assert_not_equal(0, @old_child_categories.length, “No child category found.”)
end

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,

Delegation design pattern R

July 19th, 2007

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.

[download]

screen1.jpg
best wishes,