When building highly decoupled classes I often run into the problem of how to piece it all together. I have an understanding of how each piece is supposed to interact but I'm not sure how the functionality should co-exist. I have included some sample code below.
Created
December 11, 2012 08:19
-
-
Save coop/4256846 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Project | |
attr_accessor :name | |
end | |
class Deploy | |
def initialize options = {} | |
@branch = options.fetch(:branch, 'master') | |
@cli = options.fetch(:cli, Capistrano::CLI) | |
end | |
def run | |
@cli.parse(args).execute | |
end | |
end | |
class Repo | |
def initialize project, vendor_path = Rails.root.join('vendor', 'repos') | |
@project = project | |
@vendor_path = vendor_path | |
end | |
def path | |
@vendor_path.join project.name | |
end | |
def pull | |
git.pull | |
end | |
private | |
def git | |
@git ||= Grit::Git.new path | |
end | |
attr_writer :git | |
end | |
class DeployPreparation | |
def initialize repo | |
@repo = repo | |
end | |
def prepare | |
Dir.chdir @repo.path | |
@repo.pull | |
end | |
end |
So now I have these highly decoupled classes but I am at a loss which is the best way to invoke this functionality. My immediate guess is create a helper method on Project
that exposes what I'm after:
class Project
# ...
def deploy options
options ||= {}
repo = Repo.new self
DeployPreparation.new(repo).prepare
Deploy.new(options).run
end
end
Or should I bundle up all this functionality into another class? It would be nice to be able to invoke 1 method and have a deployment run. A side benefit of bundling it up into another class would be that I could tie in backgrounding the entire process without effecting each individual part:
class DeployCoordinator
def initialize project, options
@project = project
@options = options
end
def deploy
DeployPreparation.new(repo).prepare
Deploy.new(options).run
end
alias :perform :deploy
def repo
repo = Repo.new @project
end
end
class Project
# ...
def deploy options
options ||= {}
DeployCoordinator.new(project, options).deploy
end
end
I guess it really comes down to what feels best to you as a developer, but I often find myself not knowing which is the best approach.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment