Lazy Diary @ Hatena Blog

PowerShell / Java / miscellaneous things about software development, Tips & Gochas. CC BY-SA 4.0/Apache License 2.0

ソフトウェア考古学論考 (2)

どっちかもいうとこっちが本題。

さて、ソフトウェア考古学の目的としては、

の他にも、poorly-documentedなレガシーシステムソースコードから、その仕様(あるいは意図)を読み解き復元し、システム再構築のインプットにするというケースが考えられます。

システムの技術的負債の解消や開発者の技術継承などを目的としてシステムを再構築する考え方としては、Fowler(2014)による犠牲的アーキテクチャ*1、および高橋 (2017)による式年遷宮アーキテクチャ*2が提案されています。 システム再構築にあたっては、セカンドシステム症候群を避けるためにも、まずは欲張らない(つまり、現行システムと同程度の)機能をカバーするよう開発を行うわけですが、その際これまで現行システムが本番環境で踏みつけてきた様々なコーナーケースの地雷を避けるには、現行システムの処理がなぜ現在のようになっているのかの理解が欠かせません。

ここで「システム再構築のインプットとなる設計思想の復元」を目的としたソフトウェア考古学的活動が必要になると思うのですが、そのような論文は見当たりません。とすると、

  1. アジャイルソフトウェア開発における知識の保存は成功を収めた。犠牲的アーキテクチャに基づくシステム再構築に耐え得るだけの知識を保存することができた(≒問題にならなかった)
  2. 犠牲的アーキテクチャに基づくシステム再構築は、ソフトウェア考古学的活動を伴っていない。十分な業務知識に基づくトップダウンの再設計だけで、刷新前のシステムと同程度の機能を実装できている(≒やっぱり問題にならなかった)
  3. ソフトウェア考古学的活動による設計思想の復元に成功した例はない。システム再構築は単純なストレートコンバージョンで行われている(≒成功していないので何も書けない)

のどれかなのかなぁと思うのですが、どうなんでしょうね?(3に一票入れたいのですが、悲観的に過ぎるかな?)

*1:Martin Fowler, "Sacrificial Architecture", 2014. URL: http://bliki-ja.github.io/SacrificialArchitecture/

*2:高橋征義, "青空文庫式年遷宮アーキテクチャ: 青空文庫200周年に向けて", 青空文庫20周年記念シンポジウム「青空文庫の今とこれから」, 2017. URL: https://www.slideshare.net/takahashim/aozora20th-2017

ソフトウェア考古学論考 (1)

ソフトウェア考古学(Software Archaeology)という考え方は、OOPSLA 2001で提唱されたのが始まりのようです *1Wikipediaにある通り *2 、poorly-documentedなレガシーシステムソースコードやドキュメントをどう読み解くか?というところから始まったようなのですが、現時点では、Google Scholarで調べる限り、ソフトウェア考古学の研究分野は大きく以下の2つに分かれているように見えます。

  • レガシーシステムの保守開発の効率化。poorly-documentedなレガシーシステムソースコードから、その仕様(あるいは意図)を読み解き、保守開発を確実に実施する(またはリスクを低減する)。たとえばBryon (2009)*3など。
  • システムの仕様理解の補助。昔から開発の続いているソフトウェアのソースコードの変遷やバグの出かたを変更履歴から読み解くことで、現時点のソフトウェア(これ自体はいわゆるレガシーでない場合もある)の仕様理解を助けたり、品質向上の助けにしたりする。たとえば Carrington et al. (2003)*4など。

分析に用いる手法や、その目的から見ると、後者はどちらかといえば「ソフトウェア考古学」というより「ソフトウェア発生学 (Software Embryology)」と呼ぶべきかもしれません。

現代のアジャイルソフトウェア開発においては、知識を個人でなく組織に溜め込むことで、必要なドキュメントを減らそう、それで代替できるドキュメントは作らないようにしよう、という考え方があるようです(聞いただけの話ですが……)。 ただ、ソフトウェア考古学が生まれた経緯を見るに「知識を組織に溜め込むことで、保守に必要な知識が失われないようにする」のは、果たして可能なのだろうか?ドキュメントを作らないことで、逆にソフトウェア考古学の出番が増えやしないか?という点は疑問に思っています。開発チームは存続していても、メンバーの退職・異動・昇進などのイベントを経ることで、どうしても開発開始当初に考えられていた設計上の思想はチーム内でも薄まっていきます。大量のバックグラウンドや経緯や意図を伝えるには、それに見あった量のドキュメントが必要なのでは?

アジャイルソフトウェア開発宣言がまとめられたのは2001年、今年で18年です。アジャイルソフトウェア開発の黎明期に作られたソフトウェアの開発思想や背景は、今でもチーム内に知識として保存されているのでしょうか?また、ソフトウェア考古学なしでもそのソフトウェアの保守開発に立ち向かえるのでしょうか?

*1:Ward Cunningham, Andrew Hunt, Brian Marick, Dave Thomas, "Software Archeology: Understanding Large Systems", OOPSLA 2001 Workshop, URL: https://web.archive.org/web/20100612232147/http://www.visibleworkings.com/archeology/position-papers.html

*2:https://en.wikipedia.org/wiki/Software_archaeology#cite_note-RGBH-1

*3:Bryon Moyer, "Software Archeology: Modernizing Old Systems," Embedded Technology Journal, March 4, 2009. URL: https://www.omg.org/adm/docs/Software_Archeology_4-Mar-2009.pdf

*4:Carrington, David, and S-K. Kim. "Teaching software design with open source software." 33rd Annual Frontiers in Education, 2003. FIE 2003.. Vol. 3. IEEE, 2003. URL: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.103.2003&rep=rep1&type=pdf

How to separate a string into codepoint-wise characters with PowerShell

Context:

You have a Unicode string that contain non-ASCII characters as well as ASCII characters. You want to separate that string into characters.

Problem:

If you split the string with the code below:

$TemporaryArray = $InputString -split "";
$ResultArray = $TemporaryArray[1..($TemporaryArray.length-2)];

You will have a problem: characters that represented as surrogate pair (U+10000 ~ U+10FFFF) will separated high surrogate and low surrogate (they are not character).

Reason:

PowerShell -split operator is not surrogate pair aware, and it seems by design.

Solution:

Once convert the string into UTF32 byte-array, and separate it into codepoints (4-byte length), and convert them to String object.

$ResultArray = @();
$InputStringBytes = [Text.Encoding]::UTF32.GetBytes($InputString);
for ($i=0; $i -lt $InputStringBytes.length; $i+=4) {
     $ResultArray += [Text.Encoding]::UTF32.GetString($InputStringBytes, $i, 4);
}

Limitation:

This method separate a string into each codepoint, so the Unicode ligatures (it consists of two or more codepoints) are illegally separated into codepoints. You can use icu.net for this purpose.

Difference of behavior of String#split() in Java and -split operator in PowerShell

Both of String#split() in Java and -split operator in PowerShell take regex as argument, and split string into a list or an array, but there is some difference in behavior when you pass an empty string as argument.

In Java:

System.out.println("abc".split("").length); // -> 3

Whereas in PowerShell:

PS > ("abc" -split "").Length  # -> 5

Because ("abc" -split "") makes @("","a","b","c","").

Also in PowerShell:

PS > ("abc".split("")).Length  # -> 1

Because split("") will not split the target string at all.

労働と挨拶のどちらが大切か

  • (A) 挨拶より労働の方が大切。
  • (B) 挨拶と労働が同じくらい大切。
  • (C) 労働より挨拶よ方が大切。

中井久夫「治療文化論」p.104より引用。

東京においては「あいさつ」のできることが、「はたらくこと」と並んでかなり重要であり、名古屋においては「あいさつ」よりも「はたらけること」である。