本調査研究として,進化パターン集を提供する.
ソフトウェア進化パターン集
第1.0版(2014年3月29日)
第1.1版(2014年4月3日)
第1.2版(2014年4月4日)
第1.3版(2014年4月15日)
第1.4版(2014年4月16日)
目次
- ソフトウェア進化パターンとは
- ソフトウェアプロダクトラインパターン
- コードクローンパターン
- ソフトウェア変更支援パターン
- プログラム理解支援パターン
- リファクタリングプロセスパターン
ソフトウェア進化パターンとは
ソフトウェア進化の法則[1]によると,ソフトウェアは,本質的に出荷後も利用者の要求の変化や利用環境の変化に応じて,継続的に変更され続けなければならない.この法則の科学的根拠に関しては議論の余地はあるものの,ソフトウェア開発に関わる技術者や実務者にとって,ソフトウェアの進化が避けられないという実感は強い.実際,さまざまなシステムが,仕様変更への対応の繰り返しの結果として大規模化複雑化し,保守が困難となる状況に直面している.特に,運用システムのプラットフォームの陳腐化のため,オープンプラットフォームに移行しようとするものの,現状把握のための分析コストが多大に必要になり,移行がスムーズにいかないケースも増えている.
このため,ソフトウェア進化技術に対するソフトウェア開発現場からの期待は大きく,それに関するさまざまな研究が行われている[2].また,情報システムの移行に関する研究や事例報告も存在する[3].しかし,残念ながら,それぞれの進化技術が実際のソフトウェア開発においてどのように役に立つのかを明らかにするまでに至っていない.例えば,ソースコードの進化を実現するという目的に対して,数々のプログラム解析技術が活用されていることは分かるが,それらの技術が実際のソフトウェア開発や保守において,どのように役に立つのかについては未整理なままである.
このような状況を打破するためには,ソフトウェア進化活動において,どのような場面で,どのような技術を,どのように適用すればよいのかを示す指針や慣例が必須である.つまり,技術者や実践者にとって有益な指針や慣例に焦点を当て,進化技術を整理し直すことが望まれる.
本パターン集は,このような指針や慣例をソフトウェア進化パターンとして取りまとめたものである.ここでは,以下に示す5種類のパターンを提示する.
- ソフトウェアプロダクトラインパターン
- コードクローンパターン
- ソフトウェア変更支援パターン
- プログラム理解支援パターン
- リファクタリングプロセスパターン
それぞれのパターンは,大学側メンバおよび企業側メンバで構成されたチームにおいて,それぞれのメンバの持つ問題意識や進化技術に基づく議論を通して収集されたものである.ただし,実際のソフトウェア開発・保守現場における,パターンとしての有効性に関しては未検証であることを述べておく.
ここで,本パターン集で扱うソフトウェア進化,ソフトウェアパターン,ソフトウェア進化パターンに関して,簡単に用語を説明しておく.
ソフトウェア進化(Software Evolution)
ソフトウェア進化とは,一旦出荷されたソフトウェアに対する変更を受け入れる仕組みや活動を指す.通常,個体(生物など)に対して,それ自体が変化することを進化とは呼ばない.進化とは,互いに似ている一群の個体を指す種(species)に対して,世代を越えて発生する現象である.このような観点から,単一のソフトウェアが利用者の要求や利用環境の変化に追従できなくなることをソフトウェアの老化(software aging)と呼び,ソフトウェア進化とは区別するという考え方もある[4].また,ソフトウェアにおける種をアーキテクチャ記述やプロダクトファミリのようなハイレベルなモデルで捉えることで,そのようなモデルに対する変更を進化と呼びという考え方も存在する[5].
本パターン集では,進化と老化という2つの用語を区別していない.ソフトウェア開発においては,ソースコードの一部だけを書き直したり,入れ替えたりすることで,新たなソフトウェアを構築しているとみなす傾向にある.事実,開発者にとって単一のソフトウェアを変更しているだけでも,利用者から見た機能や振る舞いが変更される(リリース番号が更新される)ことで,世代が違うように見える.このような状況において,ソフトウェア進化の実践という観点からパターンを適用する場合,ソフトウェア進化と老化というレベルで明確に区別する必要はないと考えた.
また,ソフトウェア進化は,要求分析,アーキテクチャ設計,モジュール設計,コーディング,テストなどの活動と密接な関係を持つ.よって,これらの活動に関係するパターンも進化パターンと捉えることは可能である.しかしながら,本パターン集では,このような広義の意味の進化パターンではなく,ソフトウェアリエンジニアリング(software reengineering)活動に特化したものだけを進化パターンと呼ぶことにする.
図1.1: ソフトウェアリエンジニアリング[7]
ソフトウェアリエンジニアリングとは,既存のソフトウェアを作り直す作業を指す[6].例えば,レガシーシステムのマイグレーション(legacy migration)がある.図1.1に示すように,リエンジニアリングは,リバースエンジニアリングとフォーワードエンジニアリングで構成される[6][7].リバースエンジニアリングとは,ソースコードから設計図や要求仕様を回復する活動を指す.レガシーシステムの保守において,ソフトウェアの仕様書や設計書が利用できない状況や,度重なるソフトウェアの更新によってそれらとプログラムコードの整合性が維持できていない状況は頻繁に発生する.このような状況において,プログラムコードから,より抽象度の高い表現(あるいはモデル)が構築できると,ソフトウェア理解がより容易になる.フォーワードエンジニアリングとは,要求仕様書に基づきプログラムコードを実装する従来のソフトウェア開発作業を指す.リエンジニアリングにおいて,まずリバースエンジニアリングによって,既存のソフトウェアシステムから情報を抽出し(詳細を切り捨て),より抽象度の高いモデルを構築する.次に,この抽象モデルにおいて,ソフトウェアの改良,拡張,修正を適用する.最後に,フォーワードエンジニアリングにより,新しい抽象モデルから新しいシステムを作り出す.
ここで,ソフトウェアリエンジニアリング活動にはリストラクチャリング活動も含まれる.リストラクチャリングとは,外部から見た振る舞いを変えずに,同じ抽象レベルの別の表現に変換する活動を指す.特に,既存ソフトウェアの理解性や変更容易性を向上させることを目的とした上で,外部的挙動を保存したままで内部構造を改善する活動をリファクタリングと呼ぶ[8].リファクタリングでは,大きな設計変更を小さな変換の繰り返しで実現することで挙動の保存を保証するのが特徴である.
ソフトウェアパターン(Software Patterns)
ソフトウェアパターンとは,ソフトウェア開発の特定の領域において繰り返し現れる問題とその解決策を目に見える形で体系的に表現したものである[9].これにより,ソフトウェア開発において蓄積された経験やノウハウ(know-how)を(再)利用できるようになる.
図1.2: ソフトウェアパターン
パターンの概念を図1.2に示す.通常,パターンごとに,どのような状況(文脈)で,どのような問題に適用可能であり,どのように問題を解決するのか,適用によってどのような結果(利点や欠点)が引き起こされるのか,が記述されている. ただし,パターンとは,特定の状況で発生した個々の問題に対する解法を単に集めたものではなく,状況の共通性に基づき抽象化された問題とその解法を対にして集めたものである.
開発者は,現在直面している状況や問題に合致するパターンを,既存のパターン集合(パターンカタログやリポジトリ)から,フォース(force)に着目して選択する.フォースとは,パターンを適用する際に考慮すべき要件,制約,特性(利益や不利益)を指す.また,パターン選択においては,パターンの構造や振る舞いといった機能的特性(functional property)だけでなく,性能,信頼性,保守性などの非機能的特性(non-functional property)を考慮することも重要である.
ここで,実際の開発ソフトウェア,開発プロセス,開発組織にパターンを適用する際には,具体的状況や問題に応じて,選択したパターンを具体化(修正や拡張)することが必要となる.つまり,パターンはそのまま組み込む部品ではないことを,開発者は強く意識する必要がある.また,過度にパターンを使用しないことも重要である.状況や問題に応じて適切なパターンを選択および適用しない限り,品質の高いソフトウェアを得ることはできない.パターンの選択や適用においては,フォースや結果を十分に検討してソフトウェア全体に与える影響を十分に把握する必要がある.また,検討結果によっては,パターンの適用を避けることも重要である.
ソフトウェア進化パターン(Software Evolution Patterns)
ソフトウェア進化を実践する上での指針や慣例がソフトウェア進化パターンである. Demeyerらは,ソフトウェアリエンジニアリング活動における問題とその解決方法をオブジェクト指向リエンジニアリングパターン(本パターン集では,OORPと呼ぶ)としてまとめている[7].また,リファクタリング[8]におけるコード変換は,それを適用する場面(文脈や条件)が想定されており,設計やコードに関する問題を解決するために実施される.よって,リファクタリングは,既存ソフトウェアの改変を支援する進化パターンと見なすことができる.このようなパターンを開発者や保守者が知識として備えることで,過去のソフトウェア資産を有効に活用(改善や移植)することが見込める.
本パターン集では,DemeyerらのOORPを参考に,それらを補完する進化パターンの収集を試みた結果を示す.特に,ソフトウェアプロダクトライン,ソフトウェア変更支援における履歴やマイクロブログの活用などは,OORPの出版(2002年)以降に急速に普及した概念を扱っている.さらに,コードクローン,リファクタリング,プログラム理解や変更に関する近年の技術進歩という観点から,進化パターンが追加されている.
最後に,本パターン集における進化パターンの記述形式を表1.1に示す.
表1.1: パターンの記述形式
項目 |
説明 |
名前(Name) |
パターンの内容を表す語
パターンを適用する目的(intent)を含む |
問題(Problem) |
パターンが対象とする問題
問題が発生する状況(context)や条件(condition)を含む |
解法(Solution) |
問題を解決するための方針や手順 |
議論(Discussion) |
パターンの問題や解法に関する議論点 |
トレードオフ(Tradeoffs) |
パターンの適用することで得られる良い点(pros)
パターンを適用することにより発生する悪い点(cons)
パターンの適用に関する困難(difficulties) |
根拠(Rationale) |
論理的根拠を示す資料や文献 |
実例(Example) |
パターンが適用されている例 |
よく知られた使い方(Known Uses) |
パターンが利用されている/説明されている資料 |
関連するパターン(Related patterns) |
他に参考にするとよいパターン |
|
参考文献
- [1] M. M. Lehman, M. M., “Programs, Life Cycles, and Laws of Software Evolution”, Proc. IEEE, Vol.68, No. 9, pp. 1060-1076 (1980)
- [2] 大森隆行, 丸山勝久, 林晋平, 沢田篤史, “ソフトウェア進化研究の分類と動向”, コンピュータソフトウェア, Vol.29, No.3, pp.3-28 (2012)
- [3] W. M. Ulrich, P. H. Newcomb, “Information Systems Transformation: Architecture-Driven Modernization Case Studies”, Morgan Kaufmann (2010)
- [4] D. L. Parnas, “Software Aging”, Proc. ICSE'94, pp.279-287 (1994)
- [5] M. Jazayeri, “Species Evolve, Individuals Age”, Proc. IWPSE'05, 2005, pp.3-12 (2005)
- [6] E.J. Chikofsky, and J. H. Cross II, “Reverse Engineering and Design Recovery: A Taxonomy”, IEEE Software, Vol.7, No.1, pp.13-17 (1990)
- [7] S. Demeyer, S. Ducasse, O. Nierstrasz, “Object-Oriented Reengineering Patterns”, Morgan Kaufmann (2002)
(ダウンロード)
- [8] M. Fowler, “Refactoring: Improving the Design of Existing Code”, Addison-Wesley (1999)
(訳) 児玉公信, 平澤章, 友野晶夫, 梅沢真史, “リファクタリング”, ピアソンエデュケーション (2000)
- [9] パターンワーキンググループ, “ソフトウェアパターン入門”, ソフト・リサーチ・センター (2005)
- [10] P. Clements and L. Northrop, “Software Product Line: Practices and Patters”, Addison Wesley (2001)
- [11] K. Pohl, G. Böeckle, F. J. van der Linden, “Software Product Line Engineering: Foundations, Principles and Techniques”, Springer (2005)
(訳) 林好一, 吉村健太郎, 今関剛, “ソフトウェアプロダクトラインエンジニアリング ― ソフトウェア製品系列開発の基礎と概念から技法まで”, エスアイビーアクセス (2009)
- [12] J. McGregor, D. Muthig, K. Yoshimura, P. Jensen, “Successful Software Product Line Practices”, IEEE Software, Vol. 27, No. 3, pp.16–21 (2010)
- [13] K. C. Kang, S. G. Cohen, J. A. Hess, W. E. Novak, A. S. Peterson, “Feature-Oriented Domain Analysis (FODA) Feasibility Study”, CMU/SEI-90-TR-21 (1990)
- [14] K. C. Kang, V. Sugumaran, S. Park, “Applied Software Product Line Engineering”, Auerbach Publications (2010)
- [15] L. Gorchels, “The Product Manager's Handbook: The Complete Product Management Resource”, McGraw-Hill (2000)
- [16] 位野木万里, 杉本信秀, 深澤良彰, “ステークホルダの意思決定を支援するプロダクトライン再生シナリオの提案”, ソフトウェア工学の基礎ワークショップ(FOSE2008), pp.75–80 (2008)
- [17] 神谷年洋, 肥後芳樹, 吉田則裕, “コードクローン検出技術の展開”, コンピュータソフトウェア, Vol.28, No.3, pp.29–42 (2011)
- [18] J. Humble, D. Farley, “Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation”, Addison-Wesley Professional (2010)
(訳) 和智右桂, 高木正弘, “継続的デリバリー: 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化”, アスキー・メディアワークス (2013)
- [19] P. M. Duvall, S. Matyas, A. Glover, “Continuous Integration: Improving Software Quality and Reducing Risk”, Addison-Wesley Professional (2007)
(訳) 大塚庸史, 丸山大輔, 岡本裕二, 亀村圭助, “継続的インテグレーション入門”, 日経BP社 (2009)
- [20] S. Thangthumachit, S. Hayashi, M. Saeki, “Understanding Source Code Differences by Separating Refactoring Effects”, Proc. APSEC'11, pp.339–347 (2011)
- [21] K. Herzig, A. Zeller, “The Impact of Tangled Code Changes”, Proc. MSR'13, pp. 121–130 (2013)
- [22] KDE TechBase, “Policies/Commit Policy”,
http://techbase.kde.org/Policies/Commit_Policy#Commit_complete_changesets
- [23] S. Appleton, B. Berczuk, “Software Configuration Management Patterns”, Addison-Wesley (2002)
- [24] S. Person, M. B. Dwyer, S. Elbaum, C. S. Păsăreanu, “Differential Symbolic Execution”, Proc. FSE'08, pp.226–237 (2008)
- [25] S. Lahiri and C. Hawblitzel, “Symdiff: A Language-Agnostic Semantic Diff Tool for Imperative Programs”, Proc. CAV’12, pp.712–717 (2012)
- [26] D. Jackson and D. A. Ladd, “Semantic Diff: A Tool for Summarizing the Effects of Modifications”, Proc. ICSM’94, pp. 243–252 (1994)
- [27] 角田雅照, 門田暁人, 松本健一, 押野智樹, “受託開発ソフトウェアの保守における作業効率の要因”, コンピュータソフトウェア, Vol.29, No.3, pp.157–163 (2012)