From: Robert Klemme Date: 2012-04-05T22:19:50+09:00 Subject: Re: Design pattern question James French wrote in post #1055131: > Its pretty simple really. I want to be able to call an API like this: > > SourceControl.checkout > SourceControl.update You better do sc.checkout sc.update i.e. not use a constant but an instance variable. > I want to be able to plugin different source control systems that > conform to the API. Well, in Ruby there are no interfaces so you can, but do not need to use inheritance. > My initial thought was just to go with a simple C++ style > wrapper/delegate approach: > > module SourceControl > > def self.checkout(repository, dest, options={}) > @sourceControl.checkout(repository, dest, options) > end > > def self.update(path, options={}) > @sourceControl.update(parth, options) > end > > class SourceControlAPI > > def checkout(repository, dest, options={}) > end > > def update(path, options={}) > end > > end > > end > > But I bet there is a nicer way, perhaps without having to duplicate the > API? Especially, what advantages does it have? I'd probably simply do class CVS def checkout(dest, options={}) end def update(path, options={}) end end class SVN def checkout(dest, options={}) end def update(path, options={}) end end class Perforce def checkout(dest, options={}) end def update(path, options={}) end end and then # connection sc = SVN.new("svn-repo.my.network.com", "James", "p@ssword") # repository sc.checkout("repo", "/tmp/work") do |repo| repo.update("foo") File.open(repo.path + "foo", "a") {|io| io.write("a change)} repo.submit("foo") end # auto commit sc.close # needed? You could even make SVN.new accept a block which receives "sc" and cleans up in ensure regardless how the block terminates. http://blog.rubybestpractices.com/posts/rklemme/002_Writing_Block_Methods.html Kind regards robert -- Posted via http://www.ruby-forum.com/.