Upload
hiroyuki-ohnaka
View
20.918
Download
0
Embed Size (px)
DESCRIPTION
オープニング+「実践レガシーコード」
Citation preview
高橋邦彦高橋邦彦高橋邦彦高橋邦彦高橋邦彦高橋邦彦高橋邦彦高橋邦彦
大中浩行大中浩行大中浩行大中浩行大中浩行大中浩行大中浩行大中浩行
中谷秀洋中谷秀洋中谷秀洋中谷秀洋中谷秀洋中谷秀洋中谷秀洋中谷秀洋
川西俊之川西俊之川西俊之川西俊之川西俊之川西俊之川西俊之川西俊之
13-E-4
「「「「レガシーコードレガシーコードレガシーコードレガシーコード」」」」とはいったいとはいったいとはいったいとはいったい「「「「レガシーコードレガシーコードレガシーコードレガシーコード」」」」とはいったいとはいったいとはいったいとはいったい!? !? ~~~~あなたもあなたもあなたもあなたも書書書書いてるいてるいてるいてるレガシーコードレガシーコードレガシーコードレガシーコード~~~~~~~~あなたもあなたもあなたもあなたも書書書書いてるいてるいてるいてるレガシーコードレガシーコードレガシーコードレガシーコード~~~~
自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介
�� 高橋邦彦(たかはし高橋邦彦(たかはし くにひこ)くにひこ)
��本日進行役本日進行役
�� id:id:kunitkunit
�� 新しいフレームワークを作ろうとしていろい新しいフレームワークを作ろうとしていろいろ調べているうちにろ調べているうちに REST REST とと TDD TDD の魅力の魅力
に取り付かれて今に至るに取り付かれて今に至る
�� 20082008年年55月より株式会社ディノで月より株式会社ディノで Web Web アプアプリケーション開発を行っているリケーション開発を行っている
自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介
�� 大中浩行大中浩行((おおなかひろゆきおおなかひろゆき))
�� ((株株))エルテックスエルテックス 商品開発室商品開発室
�� azusaazusa@@fieldnotesfieldnotes..jpjp / @/ @setoazusasetoazusa
�� Working Effectively With Legacy Code Working Effectively With Legacy Code 読読書会幹事書会幹事
�� SeasarSeasarプロジェクトコミッタプロジェクトコミッタ
自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介
�� 中谷中谷 秀洋秀洋((なかたになかたに しゅうようしゅうよう))
�� サイボウズ・ラボ株式会社サイボウズ・ラボ株式会社�� Web Web 間アプリフレームワーク間アプリフレームワーク flowrflowr
�� 英単語タイピングゲーム英単語タイピングゲーム iVocaiVoca
�� コンピュータと無縁の就職をするも、社長の鶴のコンピュータと無縁の就職をするも、社長の鶴の一声で、一人情シス一声で、一人情シス((兼業兼業))として内製&外注として内製&外注
�� ((中略中略))
�� 現在に至る現在に至る
自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介自己紹介
�� 川西川西 俊之(かわにしとしゆき)俊之(かわにしとしゆき)
�� 仕事では仕事ではC/C++C/C++で開発からテストまでで開発からテストまで
�� テスト管理システムテスト管理システムTestLinkTestLink
�� CC言語用言語用BDDBDDフレームワークフレームワークCSpecCSpec
それではそれでは
「レガシーコード」とはいっ「レガシーコード」とはいったいたい!? !?
~あなたも書いてるレガシーコード~~あなたも書いてるレガシーコード~
あらためあらため
現場で闘う現場で闘う
あなたに贈るあなたに贈る
レガシーコード迎撃レガシーコード迎撃
座談会座談会
副題副題副題副題::::副題副題副題副題::::
クラウドもクラウドもSaaSSaaSもも
iPhoneiPhoneもも
レガシーやろ!レガシーやろ!
スタート!スタート!
まず、皆さんにまず、皆さんに
問題問題
Q:Q:レガシーコードレガシーコード
とはいったい何とはいったい何??
A:A: COBOLCOBOLで書で書かれたコードかれたコード
A:A: Win NT 4.0Win NT 4.0用のコード用のコード
A:A: あの先輩かあの先輩か
ら引き継いだら引き継いだコードコード
その答えを求めてその答えを求めて
教科書を教科書を
ひもといてみましょうひもといてみましょう
現場で闘う現場で闘う
あなたのためのあなたのための
バイブルバイブル
※※翔泳社から翔泳社から
日本語訳出版決定日本語訳出版決定!!
レガシーコードレガシーコード
とはとは
一般には一般には「理解しづらい・変更しにく「理解しづらい・変更しにくいコードのこと」いコードのこと」
を指すかもしれないを指すかもしれない
ただ、この本にただ、この本に
よればよれば
レガシーコードレガシーコード
とはとは
ずばりずばり
テストのないコードテストのないコード
を指すを指すWorking Effectively with Legacy Code p.xvi Working Effectively with Legacy Code p.xvi
そうそう
明日あなたが明日あなたが
書くコードも書くコードも
レガシーコードレガシーコード
かもしれないかもしれない
では、私たちはでは、私たちは
いったいどうしていけばいったいどうしていけば
良いのだろう良いのだろう
それを共々にそれを共々に
考えていきましょう考えていきましょう
本日本日本日本日のののの目標目標目標目標本日本日本日本日のののの目標目標目標目標
レガシーからレガシーから逃げない逃げない
レガシーをレガシーを作らない作らない
レガシーをレガシーを作り込ませない作り込ませない
本日本日本日本日のののの目標目標目標目標本日本日本日本日のののの目標目標目標目標
そのためにそのために
各人がすべきことを各人がすべきことを
探すきっかけを作る探すきっかけを作る
それがそれが
レガシーコードレガシーコード
迎撃迎撃
座談会座談会
それでは、それでは、
ここで、ここで、
本題に入る前に本題に入る前に
レガシーを語る上でのレガシーを語る上での
基本用語を押さえましょう基本用語を押さえましょう
��Edit & PrayEdit & Pray
��Cover & ModifyCover & Modify
Edit & PlayEdit & Play
��編集し、そして祈る編集し、そして祈る
��不安を抱きながらコードを変更不安を抱きながらコードを変更
�� うまくいったと一息つくのも束の間うまくいったと一息つくのも束の間
��たまに、納品後にその不安が的中たまに、納品後にその不安が的中
��現在のソフトウェア開発の主流現在のソフトウェア開発の主流
(by Working Effectively with Legacy Code)(by Working Effectively with Legacy Code)
Cover & ModifyCover & Modify
�� カバーして、変更するカバーして、変更する
��変更の正しさ確めるテストを用意変更の正しさ確めるテストを用意
��作成したテストをセーフティネットと作成したテストをセーフティネットとしてコードを変更してコードを変更
��変更の影響がわかるので安心変更の影響がわかるので安心
�� このセッションでこれを目指したいこのセッションでこれを目指したい
ということでということで
ここからが本題ここからが本題
今日今日今日今日のおのおのおのお題題題題今日今日今日今日のおのおのおのお題題題題
��実践レガシーコード実践レガシーコード
��レガシー座談会レガシー座談会
��コミュニケーションとしてのコミュニケーションとしてのレガシーコードレガシーコード
��まとめまとめ
実践レガシーコード※フィクションです。たぶん
そのそのそのその1
////////コンストラクタコンストラクタコンストラクタコンストラクタ
publicpublicpublicpublic TooLong (String path,Map map1,Map map2,String id, IIF intf)
….
どうやって生成すりゃいいんだ?
そのそのそのその1・・・・テストケーステストケーステストケーステストケース
publicpublicpublicpublic voidvoidvoidvoid testTooLong() {
TooLong tooLong = newnewnewnewTooLong(null,null,null,null,null);….
}
→Pass Null
そのそのそのその2222
privateprivateprivateprivate DataSource dataSource;
publicpublicpublicpublic voidvoidvoidvoid doLogic() throwsthrowsthrowsthrows Exception
{
Connection con =dataSource.getConnection();
…..
}
そのそのそのその2222
InitialContext ictx = newnewnewnew InitialContext();
DataSource ds = (DataSource)ictx.lookup("java:comp/env/jdbc/SampleDS");
Field[] fields = Demo2.class
.getDeclaredFields();
forforforfor (Field field : fields) {
ifififif (field.equals("dataSource")) {
field.setAccessible(truetruetruetrue);
field.set(instance, ds);
}
}
テストのためならリフレクションも厭わず
そのそのそのその3333(Before)
Properties prop = newnewnewnew Properties();
ServletContext servletContext =
ContextFactory.getContext();
prop.put("PROP_PATH",
servletContext.getRealPath
("WEB-INF/prop.properties"));
そのそのそのその3333(After)
Properties prop = newnewnewnew Properties();
ifififif (ContextFactory.hasContext()) { // 本番
ServletContext servletContext =
ContextFactory.getContext();
prop.put("LIB_PATH", servletContext
.getRealPath("WEB-INF/prop.properties"));
} else { // テスト
prop.put("LIB_PATH", "WEB-INF/prop.properties");
}
やりすぎ?
そこで…
そのそのそのその3333(ContextFactory内内内内)
publicpublicpublicpublic staticstaticstaticstatic voidvoidvoidvoidsetContext(ServletContext fakeServletContext) {
servletContext =fakeServletContext;
}
→静的setter
そのそのそのその4
MysteriousObject obj = newnewnewnewMysteriousObject();
Result result =obj.mysteriousLogic();
//どうassertするの?
…
そのそのそのその4444
Result result =obj.mysteriousLogic();
assertEquals("ありえないリターン", result.getString());
→→→→Characterization Tests
いろいろいろいろいろいろいろいろ
� データベースのテストにはSeasar2(S2Unit)が有効� DBの操作とトランザクション管理が分離されていることが前提ですが…
� どこにテストを書くのか?�何をテストしたいのか
�→どこにバグがありそうか
�→プログラマーとしての直感を信じよう
まとめまとめまとめまとめ
�依存性を解決するために、本番コード側に手をいれることがあります
�テストを通すことよりも、今あるコードの振る舞いを明らかにすることを優先しましょう