<< 前 ホーム 次 >>

bakaid: 20121211

あのコード、Androidのですよね?Androidだったらデフォルト
値はリソースで持つのが王道ですけど。

まぁ、いいか。ちょっと面倒なんでRubyで書きますけど:

text1 = TextView.new(context)
text1.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)
text2 = TextView.new(context)
text2.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)
text1.setTextColor(Color::RED)
text2.setTextColor(Color::BLACK)
text1.setText(@name)
text2.setText(@title)

こういうコードをどう整理するかっていう話ですよね。で、
やっぱり、自分は、コンポーネントごとに整理します。

text1 = TextView.new(context)
text1.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)
text1.setTextColor(Color::RED)
text1.setText(@name)

text2 = TextView.new(context)
text2.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)
text2.setTextColor(Color::BLACK)
text2.setText(@title)

そうすると、メソッドに切り出したくなる。

text1 = newText1(context)
text2 = newText2(context)

def newText1(context)
  text1 = TextView.new(context)
  text1.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)
  text1.setTextColor(Color::RED)
  text1.setText(@name)
  return text1
end

def newText2(context)
  text2 = TextView.new(context)
  text2.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)
  text2.setTextColor(Color::BLACK)
  text2.setText(@title)
  return text2
end

そうすると、今度は似た部分を切り出したくなる。

text1 = newText1(context)
text2 = newText2(context)

def newText1(context)
  return newText(context, Color::RED, @name)
end

def newText2(context)
  return newText(context, Color::BLACK, @title)
end

def newText(context, color, text)
  text = TextView.new(context)
  text.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)
  text.setTextColor(color)
  text.setText(text)
  return text
end

そうすると、今度は引数をパラメータ化したくなる。

text1 = newText1(context)
text2 = newText2(context)

def newText1(context)
  return newText(context, {:color => Color::RED, :text => @name})
end

def newText2(context)
  return newText(context, {:color => Color::BLACK, :text => @title})
end

def newText(context, params)
  text = TextView.new(context)
  text.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)
  text.setTextColor(params[:color]) if params.key?(:color)
  text.setText(params[:text]) if params.key?(:text)
  return text
end

そうすると、今度はパラメータをまとめたくなる:

texts = [ 
  {:color => Color::RED,   :text => @name},
  {:color => Color::BLACK, :text => @title}
]

text1 = newText(context, texts[0])
text2 = newText(context, texts[1])

def newText(context, params)
  text = TextView.new(context)
  text.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)
  text.setTextColor(params[:color]) if params.key?(:color)
  text.setText(params[:text]) if params.key?(:text)
  return text
end

lots of small piecesからonce and only onceへと流れて
いくわけです。

パラメータを別ファイルにしてrequireすれば、それも一種の
リソースファイルということになります。Rubyのような
インタプリタ言語ではよくやるんじゃないかと思います。

やっちゃいけないのが、横に切るやり方:

text1 = TextView.new(context)
text2 = TextView.new(context)

text1.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)
text2.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)

text1.setTextColor(Color::RED)
text2.setTextColor(Color::BLACK)

text1.setText(@name)
text2.setText(@title)

一見これもlots of small piecesにできそうなんですけど、
実は非常にリファクタリングしにくいんですね。このまま
リファクタリングしていくと:

textViews = [TextView.new(context), TextView.new(context)]
textViews.each{|text| text.setTextSize(TypedValue::COMPLEX_UNIT_DIP, 24)}
colors = [Color::RED, Color::BLACK]
texts = [@name, @title]
textViews.each_with_index{|text, i| text.setTextColor(colors[i])}
textViews.each_with_index{|text, i| text.setText(texts[i])}

みたいな形になって、新しいTextViewを増やすのが面倒に
なるんです。パラメータをまとめたくなるようなコードにも
ならない。

本家Permlink

<< 前 ホーム 次 >>


Copyright © 1905 tko at jitu.org

バカが征く on Rails