テーマ。論理凝集をどのように解消するか。
これが最初の DRY ではない状況。
# $use_real_db optional. using mock DB for default.
sub test_object {
my ($expect, $use_real_db) = @_;
if ($use_real_db) {
my $object = new My::Object(real_db());| #! ruby | |
| # coding: utf-8 | |
| # | |
| # http://d.hatena.ne.jp/nowokay/20090409#1239268405 | |
| require 'expectations' | |
| Expectations do | |
| # boolean | |
| t = (-> x { (-> y {x}) }) |
| #!/bin/bash | |
| # .bashrc か .bash_profile に | |
| # | |
| # export PATH=$HOME/libexec:$PATH | |
| # | |
| # を追記しておく (既存の export PATH があるなら $HOME/libexec を追加) 。 | |
| src_path=$HOME/.src | |
| exec_dir=libexec | |
| package_dir=pkg |
| #!/bin/bash | |
| # .bashrc か .bash_profile に | |
| # | |
| # export PATH=$HOME/bin:$PATH | |
| # | |
| # を追記しておく (既存の export PATH があるなら $HOME/bin を追加) 。 | |
| src_path=$HOME/.src | |
| exec_dir=bin | |
| package_dir=pkg |
| module Builder | |
| def self.method_missing name, *args, &block | |
| tag = Tag.new | |
| tag.send(name, *args, &block).flatten.join | |
| end | |
| class Tag | |
| def initialize | |
| @tags = [] | |
| end |
テーマ。論理凝集をどのように解消するか。
これが最初の DRY ではない状況。
# $use_real_db optional. using mock DB for default.
sub test_object {
my ($expect, $use_real_db) = @_;
if ($use_real_db) {
my $object = new My::Object(real_db());| module Static | |
| def static! method_name, var_name, &block | |
| instance_eval do | |
| @static_vars ||= {} | |
| namespace = {:method_name => method_name, :var_name => var_name} | |
| def namespace.identifier | |
| self.to_s.to_sym | |
| end | |
| reminder = proc { @static_vars[namespace.identifier] } | |
| define_method(method_name) do |
| # g.rb | |
| cache = "" | |
| klass = class<<self; self; end | |
| klass.send(:define_method, :foo) do | |
| lambda {|s| cache += s; cache } | |
| end | |
| # call_foo.rb | |
| require './g' |
| module Static | |
| cache = "" | |
| klass = class<<self; self; end | |
| klass.send(:define_method, :foo) do | |
| lambda {|s| cache += s; cache } | |
| end | |
| def self.out_of_scope | |
| cache | |
| rescue |
OOP とトップダウンの構造化プログラミングの設計上の違いとしてわかりやすいのは、 フローごとの動作の差異をどこが担保するかだと思います。
決済で、キャリア決済とクレジットカードによる決済を実装しようとしたとき、 トップダウンの場合、
case payment_method
when :carrier
do_carrier_paymentファイル準備
mv Rakefile Rakefile.plain
vim Rakefile.bundler
ln -s Rakefile.bundler RakefileRakefile.bundler の中身
# Rakefile.bundler