臭い名
ドキュメントに存在するシーケンシャルなデータからコードの断片を生成する
臭い英名
sequential data in document
臭い状況
仕様書や要件定義書や資料をもとにコードを記述する機会があります。
仕様書等に大量のシーケンシャルな値がある場合、目で見て一つ一つコードを記述すると
時間がかかるものです。
コピペするにしても数が多いと手間がかかります。
この場合、ドキュメントのシーケンシャルデータとソースコードの形式が一定のルールでひも付いていれば
変換用のスクリプトを用いてコードを書くことが可能になります。
リファクタリング名
シーケンシャルデータからコードの断片を生成
リファクタリング英名
generate code fragment from sequential data in document
改善理由
・手作業によるミスをなくす
・手作業による作業時間を減らす
・仕様変更時の工数を減らす
対応
・ドキュメントのシーケンシャルデータをリストに抽出する
・シーケンシャルデータをループで処理しながらコードのボイラーテンプレートにはめ込む
・結果をコピーしてソースコードにはめ込む
※ソースコードのパースが容易なら処理結果をコードに埋め込むスクリプトを生成するとさらに効率が上がる
サンプル
仕様
・Excelにある大量のシート名とソート順の組み合わせをJavaのMapとして定義する。
・ExcelのシートからRubyでシート名の一覧を取得する=>下記記事参照
Ruby | Excelのシート名を一括取得し、標準出力する
http://d.hatena.ne.jp/tbpg/20130625/1372169541
・取得したシート名リストを元にコードテンプレートを適用した大量のSheetsSortのコンストラクタ呼び出しのコードを生成する。
・結果をJavaのクラスにペーストする
Map設定用クラス
「// #start#、// #end#」の間に自動生成したコードを反映する
再実行ができるように「// #start#、// #end#」は生成後も残しておく
class SheetsSortSetting { public Map<SheetsSort> getSheetsSort() { Map<String, Integer> map = new HashMap<>(); // #start# // #end# return map; } }
シート名の一覧取得(excel_sheets.rb)は下記参照
Ruby | Excelのシート名を一括取得し、標準出力する
http://d.hatena.ne.jp/tbpg/20130625/1372169541
ソースコード生成用スクリプト(map_code_generator.rb)
# encoding: utf-8 require_relative "standard_io" require "pp" class SourceReplacer include StandardIo validate_file 0 def replace_placeholder(replace_code) output_file = $*[0] source = read_file(output_file) write_file(output_file, source, replace_code) end def read_file(output_file) source = "" File.open(output_file, "r") do |f| source = f.read end return source end def write_file(output_file, source, replace_code) source.gsub!(%r|// #start#(.*\n){0,}// #end#|, "// #start#\n#{replace_code}\n// #end#") File.open(output_file, "w+") do |f| f.print source end end end replace = "" $*[1..($*.size)].each_with_index {|key, cnt|replace << " map.put(\"#{key}\", #{cnt + 1});\n"} replace.chop! sr = SourceReplacer.new exit unless sr.validate sr.replace_placeholder(replace)
実行コマンド
ruby excel_sheets.rb hoge.xlsx | xargs ruby map_code_generator.rb SheeetsSortSetting.java
実行後のSheeetsSortSetting.javaクラス
class SheetsSortSetting { public Map<SheetsSort> getSheetsSort() { Map<String, Integer> map = new HashMap<>(); // #start# map.put("hoge", 1); map.put("hage", 2); map.put("hige", 3); // #end# return map; } }
入力Excelにシートを追加
実行後のSheeetsSortSetting.javaクラス
class SheetsSortSetting { public Map<SheetsSort> getSheetsSort() { Map<String, Integer> map = new HashMap<>(); // #start# map.put("hoge", 1); map.put("hage", 2); map.put("hige", 3); map.put("poge", 4); map.put("page", 5); map.put("pige", 6); // #end# return map; } }
備考
もう一段階進めてbat or shell化しておけばrake,gradle,mavenと連携してもう一段階自動化できます。
それはあくまでrake等の機能なので今回は割愛。