プログラミング

2022/01/09

「RubyやRailsは終わった」という記事のリンク

「RubyやRailsは終わった」という記事があったが本当なのか?
見つけた記事だけをリンクしておく。
自分が後で読むためのメモ書き。

【参考】
“Rubyは死んだ”のか? まつもとゆきひろ氏が語る「プログラミング言語サバイバル」とRubyの未来 - Part1 - ログミーTech

Ruby2系はチームの幸福度を最大化できなかった - Qiita

「Railsは終わった」と言われる理由 - Qiita

Rubyは死んだというが。流行り廃りに拘らず、便利なものは活用すればいいのに - Qiita

Rubyは果たして死んだのか | 日経クロステック(xTECH)

Rubyは終わった?将来性と今後の展望をまとめてみた│エンジニアハック

将来性のないプログラミング言語5選として「Ruby」が挙がり話題に | スラド IT

個人的にはRubyは好きだ。
メタプログラミングRuby 第2版」を読んで、色々動かして、やっとダックタイピングの意味が分かった。
やはりRubyはJavaとは違う。
Rubyは究極のオブジェクト指向言語なのかもしれない。

また、Rubyというコミュニティも素晴らしいと思う。

なぜソフトウエア後進国の日本でRubyは成功したのか?~ソフトウェアの成功の秘訣はコミュニティ、そしてコンウェイの法則にある: プログラマの思索

一方、RubyはPerlのシンタックスを受け継ぐ部分があるせいか、初心者には読みにくい記法がある。
慣れないと使いこなせない部分もある。

「Rubyのしくみ」を読んだ後のRubyの感想: プログラマの思索

Ruby技術者認定試験の感想: プログラマの思索

Ruby初心者が間違いそうなこと: プログラマの思索

メタプログラミングRubyの感想: プログラマの思索

Rubyのブロック、Proc、lambdaのメモ: プログラマの思索

RedmineやRubyについては今後も追いかけていく。


| | コメント (0)

プログラミングしてる時はでっかいピタゴラ装置を作ってるみたいな感じ

「プログラミングしてる時はでっかいピタゴラ装置を作ってるみたいな感じ」というツイートを見つけたすごく共感した。

【参考】
Rui UeyamaさんはTwitterを使っています 「少数派の意見かもしれないけど、プログラミングしてるときはでっかいピタゴラ装置を作ってるみたいな感じで、数学が関係ある感じがあんまりしない。」 / Twitter

結城浩さんはTwitterを使っています 「@rui314 デバッグしてるときと証明読んでるときはなんか似てる。素直に読みつつ穴探ししてるみたいな感覚。」 / Twitter

英語勉強中さんはTwitterを使っています 「@rui314 めちゃくちゃわかります。僕は書いてるとき数学のことなんか考えてないです」 / Twitter

akipiiさんはTwitterを使っています 「プログラミングはこの感覚に近いな」 / Twitter

プログラミングは「ブロックを組み合わせる」感覚に似ている: プログラマの思索

「プログラミングのできる羊とできない山羊を区別する方法」の記事のリンク: プログラマの思索

「60%の人間はプログラミングの素質がない」記事のリンク: プログラマの思索

プログラマに必要なスキル: プログラマの思索

プログラムを書いている時、数学の知識を使っているかと言われるとそうではない気がする。
むしろ、APIやFWのライブラリをまずは頭に叩き込んでおき、自分が実装したい目標に対して、それらAPIをどうやって組み合わせて意図通りに動かすか、に注力している。
ちょうど、ブロックで巨大な積み木を組み立てている感じに似ている。

だから、「プログラミングしてるときはでっかいピタゴラ装置を作ってるみたいな感じ」にはとても共感するし賛同する。

たとえば、RDBでSQLをデータ抽出したり、機械学習や深層学習のライブラリを使って母集団を推定したり、マーケットを予測したり、Web上の通信を暗号化したりする時、数学の理論はAPIやライブラリの中に隠れてしまっている。
それらライブラリを呼び出すだけで、高尚な理論を使えるのは素敵だが、だからと言って、プログラミングが楽になっているわけではないと思う。

一方、やりたいことを実現するには、PythonやRDB、Webサーバー、Dockerなどの開発環境を揃えて、Githubで構成管理し、CIツールでビルド&デプロイできるようにして、Jupytorを動かせるようにしたり、IntelliJなどの開発環境を構築したり、とプログラミングの前準備がすごく多い。
普通の初心者はこの部分で挫折するのだろうと思う。

僕自身、新しい環境を揃えてプログラミングスタイルを覚える時は割と苦痛に感じる時もあった。
Ruby on Railsもそうだし、AWSでの環境構築、GNS3でのCiscoルータ&スイッチの環境構築の時もそうだ。
Python+Anacondaはまだマシだった。
プログラミングは奥が深い。

| | コメント (0)

2021/07/23

値オブジェクトの設計がオブジェクト指向モデリングの最初の登山口

先日7/14に開催された「アジャイル開発におけるモデリング活用実践セミナー」のオンライン動画を見ていて、興味深かった。
羽生田さん、増田さん、原田さん達の会話が面白かった。
気になった発言をラフなメモ。
自分の感想も混じっていて、全くロジカルでない。

【参考】
「アジャイル開発におけるモデリング活用実践セミナー」(2021.07.14開催) - UMTP 特定非営利活動法人UMLモデリング推進協議会

ドメイン駆動設計が好きで、ベンチャー企業のWebサービスの開発で使っている

最近は、基幹系システムのリプレースでドメイン駆動設計を使いたい、という話も多く来ている
すごく難しいけど、やりがいもあるし面白い

オブジェクト指向モデリングのワークショップでモデルを書こうとすると、みんな、フレームワークが前提でモデルを書いてしまう
ドメインの外側ばかり話している
肝心のドメインをプログラミングしようとすると、意外に誰も書けない
まずは値オブジェクトから始めよう
みんな、値オブジェクトでプログラミングできない
増田さんのオブジェクト指向モデリング本「現場で役立つシステム設計の原則 ~変更を楽で安全にするオブジェクト指向の実践技法」は、値オブジェクトから書こうとしているのでお勧め

intやStringのデータ型だけではトランザクションスクリプトみたいに書いてしまう
値オブジェクトが大事
オブジェクト指向では、Immutableな値オブジェクトから始まる
関数的プログラミングとも相性がいい
ドメインに特化してプログラムを書こうとすると、必ず値オブジェクトから始まる
値オブジェクトの設計がオブジェクト指向モデリングの最初の登山口

エンティティを重視するとデータモデリングになってしまう
手続き型プログラミングで、でかいエンティティを書いて、長いトランザクションスクリプトを書くと失敗する
書いていて怖い
データモデリングとオブジェクト指向モデリングは違うと考えた方がいい

エリック・エヴァンスのDDD本「エリック・エヴァンスのドメイン駆動設計」に出てくる例では、OODBを使っていた
昔はデータのストアはOODBでいい、という感じだった
OODBでは性能が出ないので廃れた

業務の複雑さに関するデータのモデリングは、データモデリングの方が一日の長がある

1990年代にモデリングが盛んだったのに、現代ではモデリングが廃れたのは、モデリングが伝承されなかったからではない
むしろ、現代的な課題に対して、長年知られていたモデリング手法のこの部分は今も使えるが、この部分は今は使えない、という交通整理された本がほしいね

2010年代にピアソン本が絶版されたので古いオブジェクト指向モデリング本が手に入らなくなり、エリック・エヴァンスのDDD本「エリック・エヴァンスのドメイン駆動設計」だけが唯一残った
そのために、オブジェクト指向モデリングの歴史に断絶がある

メソッドは3個まで
それができない人は、クラス化、カプセル化が分かってない
入出力処理は手続き型になりやすい

顧客との対話では、UMLを普通に使う
ただし、アクティビティ図、コンテキスト図、データフロー図を使う場合が多い
システム要件に落とす時は、UMLをガンガン使う

要件定義でモックを作るときはHTMLを使う
最近はいい感じですぐにモックデザインが作れる
実データを画面で見せた方が早い

プロダクトオーナーとの対話では、RDRA2.0を使って話する時が多い
システム設計では、UMLを使っている
図を書くのが目的ではなく、会話や意思決定のために使っている

DDDのエンティティはミュータブル?イミュータブル?
Webならイミュータブルが普通でしょ
setter, getterと無関係なモデルにしている
イミュータブルが普通
エンティティに状態は持たせない
void実行でなく、新しい状態のオブジェクト、エンティティを別で返す
Webならイミュータブルが普通
エンティティの状態をSetして変更すると、バグが出そう
イミュータブルだからFreezeしているのでCloneする必要もない

アジャイル開発プロセスとモデリング作業の事例は?

モデリングでも、概念モデルのレベルでプログラミングを書く
合わせてDFDやER図を書く
事業分野の可視化はシステムで書きにくいので、シナリオ、バリューチェーンを書く
バリューチェーンで、どこのプロセスに差別化要素があるか、強みがあるか、を分析する
ビジネスを理解するモデリングとシステムとして動かすプロトタイプの2つを行き来している

増田さんのドメインモデルのサンプルが分かりやすい
パッケージ図でクラス図を分割して、HTMLで一覧にしている
さらに、ユースケースのシナリオからパッケージ図、クラス図まで一気通貫でHTMLにしている
軽量で明快なモデリング
ビジネスモデルとDFD・ER図をつなぎつつ、パッケージ図・クラス図で方にしてHTMLで見せている
増田さんのクラス図は値オブジェクトが中心
取引日、貸し出しも全てクラスになっている
増田さんにとって、モデル駆動とはドキュメント駆動のイメージ
ソースコードとモデルを行き来していて、モデルが自然にドキュメントになっている

Scrumで開発する時に、ユーザーストーリーマッピングを使う場合が多い
このメソッドを実装する時、このメソッドはこの要件から来ていて、この要件はユーザーストーリーマッピングのこの部分に対応する、と辿れる

【感想】
エリック・エヴァンスのドメイン駆動設計現場で役立つシステム設計の原則 ~変更を楽で安全にするオブジェクト指向の実践技法を読むと、ドメインのソースコードが値オブジェクトになっている場合が多い。
その理由は、ドメインをプログラミングに注力しているから、と見ると分かりやすい気はする。
オブジェクト指向でプログラムを書くと、状態を持たせるエンティティが頻出して、バグが出やすい箇所はたいていその部分であり、デバッグしないと追跡できない場合が多いのを思い出した。

| | コメント (0)

2021/07/11

組込ソフトウェア開発のための3部作「構造化モデリング」「オブジェクト指向モデリング」「リバースモデリング」を読んでいて楽しい

組込ソフトウェア開発のための3部作「構造化モデリング」「オブジェクト指向モデリング」「リバースモデリング」を読んでいて、面白いのでメモ。
10年以上も前にかおるんさんは既に読破されているので参考にしている。

【参考】
読了・組み込みソフトウェア開発のためのオブジェクト指向モデリング - ブログ@kaorun55

読了・組込みソフトウェア開発のための 構造化モデリング - ブログ@kaorun55

【1】上記のブログでは、「組み込みとしては、やはりこちら(構造化)の方がしっくりくる。なんとなくオブジェクト指向の方は無理をしている気がしてならない。」という感想がある。
オブジェクト指向モデリング」よりも「構造化モデリング」の方がしっくり来るらしい。

一方、僕は、構造化設計の技法は、データフローダイアグラムとかSTS分割のような古い技法に違和感があって、むしろ、オブジェクト指向設計の方針でクラス図、シーケンス図、状態遷移図からモデルを作り出す方がしっくり来る。
だから、「構造化モデリング」よりも、「オブジェクト指向モデリング」の方が、読みやすく感じた。
なぜなら、オブジェクトで考える方がレイヤ化設計、状態遷移図などのモデルを自然に組み立てられる気がするから。

【2】たとえば、組込みSW開発の経験はゼロだが、組込みSWのモデルをユーザ視点の業務ロジック層と、物理法則やセンサーから検知した情報の制御を含む制御層の2つに大きく分けてモデルを組み立てる方針の場合、オブジェクト指向設計の方がパッケージでソフトェアを分割してレイヤ化しやすい利点があると思う。

以前、astah関西で、高井さんがSysMLを使う利点として、熱力学など自然科学の専門家、自動車や家電機器などの業務の専門家、ハードウェアの専門家、そして組込みSWを開発するプログラマの4種類の人達が、SysMLを通じてコミュニケーションできるようになった、という話もあった。

第2回astah関西の感想 #astahkansai: プログラマの思索

また、状態遷移図とは、一つのオブジェクトに着目してその状態が遷移した過程を表すので、クラス図で洗い出したオブジェクトから自然に状態遷移図で考えるように仕向けられる。

組み込みソフトウェアの根本問題~対象物の状態遷移を記述できれば、制御が可能だ: プログラマの思索

【3】興味深いのは、組込みSW開発の要件定義で重要な成果物として、ユーザ視点のユースケース分析だけでなく、イベントリストも挙げられている点だ。
たとえば、「構造化モデリング」「オブジェクト指向モデリング」の例では、電気ポットのソフトウェア要件定義で、ユーザがお湯を沸かすときのイベントだけでなく、ポットの水位やポットのお湯の温度の変化がトリガーとなるイベントも洗い出されている。
考えてみれば当たり前だが、アクターとして、ポットの購入者という利用者だけでなく、ポットという機械を構成するセンサー部品(水位の検知、温度の検知)もアクターになるわけだ。
つまり、組込みSW開発では、アクターの種類が多いので、コンテキスト図を最初に描くのが割と重要と気づいた。

【4】もう一つの「リバースモデリング」は読みかけだが、よくある事例な気がして、興味深く読んでる。
レガシーな業務システムと同じく、組み込みソフトウェアもレガシーになると、設計書はなくなっていて、動くソースコードが仕様そのものになっている。
しかし、数千行、数万行、数十万行のソースコードから本来の設計思想を汲み取って開発するのは至難の業だ。
たとえば、工場の生産ラインとか、長年使われている機械部品とか、そういう例があるのだろう。

リバースモデリング」では、レガシーと化したソースコードからリバースして、モデルを抽出し、本来のあるべきモデルを描き出し、そこから仕様変更や改修を手がけていく、というストーリー。
なかなかうまく行かないだろうが、色んな技法を駆使して、リバースしたモデルを洗練させていくのは面白い。
今なら、XDDPと組合せてやるだろうか?

【5】残念なことに、組込ソフトウェア開発のための3部作「構造化モデリング」「オブジェクト指向モデリング」「リバースモデリング」は、「構造化モデリング」以外は絶版になっている。
3部作全てが復刊されるといいなと思う。


| | コメント (0)

2021/04/10

テスト駆動開発が抱える問題は可読性と保守性のトレードオフ #dxd2021 #streamA

@t_wadaさんがテスト駆動開発のライブコーディングをやっていて、歩きながら聞いていた。
@t_wadaさんがブツブツつぶやいてくれているので、画面を見なくても、聞くだけで想像できる。
まるで、テスト駆動開発のラジオドラマみたいな感じだ。

Developer eXperience Day CTO/VPoE Conference 2021 - connpass

akipiiさんはTwitterを使っています 「#dxd2021 #streamA @t_wada さんのライブコーディングを歩きながら聞いていて、低い声質が良いし、テスト駆動のコメントや呟きがDJみたいて聞きやすい。バグ修正とリファクタリングは分けましょうね、とか、独り言みたいな呟きが自分事でリアルに感じる」 / Twitter

@t_wadaさんの呟きで面白かった点を記録しておく。

テストプログラムを書いていると、バグ修正とリファクタリングが混じってしまう時がある。
お勧めは、バグ修正だけに注力するか、リファクタリングだけに注力するか、モードを意識的に切り替えること。
思い通りの動きにならない時に、バグ修正とリファクタリングが入り交じるのはお勧めしない。

テストプログラムを書いていくと、テストプログラムがドキュメントそのものになる。
すると、状況の下に機能を置くか、機能の下に状況ごとに書いていくか、どちらかの方針がある。
どちらも正しい。

テストプログラムの観点では、状況の下に機能を書く方が、書きやすい。
状況はグローバル変数として共通化されるので、ソースコードは短くなるので保守性は高くなる。
しかし、機能が直感的に分からないから可読性は低くなる。

一方、機能の下に状況ごとにツリー構造にロジックを書いていくと、テスト仕様書のようになるので読みやすい。
機能のツリー構造は、業務システムアプリとかWebアプリのメニューみたいなものだから、どこに機能があるのか探しやすい。
しかし、状況があちこちに散らばるので、重複したソースコードが多くなり、保守性は下がる。

つまり、テストプログラムの可読性と保守性はトレードオフになる。
どちらが正しい、というわけではない。
テストプログラムを書く人の永遠の問題。

そこで、このトレードオフを緩和するために、パラメトライズド・テストプログラミングのテクニックがある。
つまり、テストメソッドやテストプログラムをパラメータで増やすやり方がある。
これにより、テストプログラムを機能別に書いたとしても、状況をパラメータとして増やすことができて、テストプログラムの可読性を保持するとともに、保守性も高める。

テスト駆動開発がXPで出てきてからもう20年も経つ。
改めて聞いて、色々気づきがあってよかった。





| | コメント (0)

2020/05/08

Ruby技術者認定試験の感想

Ruby技術者認定試験Silver・Goldに合格したので感想をメモ。
Ruby初級者なので、間違っていたら後で直す。

【参考】
Ruby技術者認定試験

Ruby技術者認定試験のGoldに受かったので感想 - 模索中

Ruby技術者認定試験(Silver && Gold)合格体験記 | Avintonジャパン株式会社

ruby gold 2.1 - Qiita

Ruby技術者認定試験のGoldに受かったので感想 - 模索中

新人プログラマがRuby技術者認定試験(Gold 2.1)に1ヶ月半以内で合格する勉強法 - IT女子ブログ

Ruby初心者だけどRuby Association Certified Ruby Programmer Silverを取得した! - suusan2号の戯れ

Ruby技術者認定試験 Goldを受験しました - ZENET Tech Blog

【1】Ruby技術者認定試験Silver・Goldは、とても良い試験だったと思う。

Rubyの文法やライブラリを一通り知っておく為に勉強せざるを得ない環境にできること、そして、初級者はSilver、中級者はGold、というように、レベルも上手く設定されているからだ。
特にGoldは、メタプログラミングの知識や経験がないと合格は難しい。
Ruby経験者、Rails経験者であっても、一夜漬けでは合格できないだろうと思う。

【2】試験対策は、Ruby技術者認定試験にあるオンラインの模擬試験を100点が取れるまで解くこと、推奨の書籍3冊を読み込むことだった。

オンラインの模擬試験はたぶん、Ruby実務経験があっても試験慣れてしていないと取りこぼすかな、と思う。
間違えた問題は、ミスした原因を分析して、理解できていないのか、分かっているのに勘違いしたのか、でふるい分けて、Webや書籍で調べて納得するまで腹落ちさせることが大事。

【3】お勧めの書籍は5冊ある。
「Ruby公式資格教科書 Ruby技術者認定試験 Silver/Gold対応」
「メタプログラミングRuby第2版」
「Rubyのしくみ Ruby Under a Microscope」
「改訂2版 Ruby逆引きハンドブック」
「Effective Ruby」

【3-1】「Ruby公式資格教科書 Ruby技術者認定試験 Silver/Gold対応」に記載の模擬試験は必ず解いておくべき。本試験でも割と同じ問題が出るときもある。

【3-2】「メタプログラミングRuby第2版」はとても良かった。
Rubyにあって、Javaにはない特徴がメタプログラミングにあると思う。
Rubyの面白さはここにあると思う。
Javaの経験に引きずられていたので、サンプルを写経してようやく、ダック・タイピングのイメージがつかめてきた。

たとえば、io.print という処理では、ioはFileオブジェクトかもしれないしIOオブジェクトかもしれないし、printはインスタンスメソッドではなくインスタンス変数かもしれない。
つまり、的確にオブジェクトを定義すれば、ポリモルフィズムが背後で上手く動作して、たった一つの表現で複数パターンの処理を実現できる。
さらに、Rubyは読みやすさを重視しているので、処理がそのまま英文であるかのように読める。
特に、内部DSLをRubyで表現する時はそうだ。

「メタプログラミングRuby第2版」の良かった点は2つある。
まず、Railsの仕組みを紹介してくれていること。

たとえば、ActiveRecord::Baseでは、インスタンスメソッドが300個以上、クラスメソッドが500個以上も含まれている巨大なクラスだ。
著者が言う通り、Javaプログラマならば、こんな設計は狂っている、スパゲティコードだ、と最初は思うだろう。
しかし、むしろRailsでは読みやすく変更しやすい設計になっているのだ。
つまり、著者の言う通り、設計技法は絶対的なものではなく、設計技法は使用言語によって変わる。

その他に、ActiveSupport::Concernは進化的設計から生まれたし、alias_method_chainは廃止されてprependが使われる設計に変わった。
つまり、最初は問題解決のためのシンプルなコードを書いて、その後、ゴーストメソッド多用に対するパフォーマンス改善やalias_method_chain多用に対するスパゲティコード対策などのために、どんどんフレームワーク設計そのものを変えていった。
すなわち、Rubyのやり方は、最初から正しい設計を行うよりも、後から機能改善やパフォーマンスを改善していく進化的設計、つまりアジャイル開発がとても向いている。
その理由は、Rubyが徹底したオブジェクト指向言語でありメタプログラミングしやすい特徴を持つので、とても柔軟性の高い言語だからだろう。

【3-3】「メタプログラミングRuby第2版」の付録「よくあるイディオム」は、Ruby初級者が暗記すべきテクニックと思う。
参照したいので、イディオムを載せておく。

O’Reilly Japan - メタプログラミングRuby 第2版

アラウンドエイリアス(Around Alias)
ブランクスレート(Blank Slate)
クラス拡張(Class Extension)
クラスインスタンス変数(Class Instance Variable)
クラスマクロ(Class Macro)
クリーンルーム(Clean Room)
コードプロセッサ(Code Processor)
コンテキスト探査機(Context Probe)
あとで評価(Deferred Evaluation)
動的ディスパッチ(Dynamic Dispatch)
動的メソッド(Dynamic Method)
動的プロキシ(Dynamic Proxy)
フラットスコープ(Flat Scope)
ゴーストメソッド(Ghost Method)
フックメソッド(Hook Method)
カーネルメソッド(Kernel Method)
遅延インスタンス変数(Lazy Instance Variable)
ミミックメソッド(Mimic Method)
モンキーパッチ(Monkeypatch)
ネームスペース(Namespace)
nilガード(Nil Guard)
オブジェクト拡張(Object Extension)
オープンクラス(Open Class)
Prependラッパー(Prepended Wrapper)
Refinements(Refinements)
Refinementsラッパー(Refinements Wrapper)
サンドボックス(Sandbox)
スコープゲート(Scope Gate)
自己yield(Self Yield)
共有スコープ(Shared Scope)
特異メソッド(Singleton Method)
コード文字列(String of Code)
SymbolのProc変換(Symbol To Proc)

メタプログラミングRubyの感想: プログラマの思索

【3-4】「改訂2版 Ruby逆引きハンドブック」は、Rubyのライブラリを一通り説明してくれているので、APIを調べたい時に便利。

特に、RubyでもJavaでも、どんなプログラミング言語でも、配列Array、連想配列Hash、文字Stringのメソッドは最低限必ず覚えておくべき。
なぜなら、配列やハッシュ、文字を自由自在に操れないと、自分がやりたいことを実現する手間が多くなりすぎて、イライラするから。
もちろん、それ以外にもファイル処理、Web操作、クラス設計なども必要。

Java経験者から見ると、RubyはArrayやHashのライブラリが非常に多いし、便利な使い方が多いように思う。
Rubyはブロックが使いやすいので、ArrayやHashの各要素に何らかの処理を一括操作したい時に、1つのメソッドで1行で書ける場合が多い。
VBやJavaならば数行もまどろっこしく書いてしまう部分が簡単に書けるのは素晴らしい。
但し、たとえば、mapとcollect、selectとfind_all、injectとreduce、findとdetectなどのように、異音同義語が多い点は注意。

「改訂2版 Ruby逆引きハンドブック」は今も愛用している。

Ruby初心者が間違いそうなこと: プログラマの思索

SmalltalkとLispから来たメソッドmap と collect、reduce と inject: プログラマの思索

【3-5】「Effective Ruby」はRubyらしい書き方の解説本。
最初はRubyらしい書き方が分からず、VBやJavaみたいな書き方になってしまっていた。
その原因は、Rubyのライブラリを幅広く深く知っていないこともあったが、Ruby独特の考え方や書き方が分かっていなかったからと思う。

僕は、下記が参考になった。

項目1 Rubyは何を真と考えているかを正確に理解しよう
項目2 オブジェクトを扱うときにはnilかもしれないということを忘れないようにしよう
項目6 Rubyが継承階層をどのように組み立てるかを頭に入れよう
項目12 さまざまな等値の違いを理解しよう
項目15 クラス変数よりもクラスインスタンス変数を使うようにしよう
項目18 要素が含まれているかどうかの処理を効率よく行うために集合を使うことを検討しよう
項目19 reduceを使ってコレクションを畳み込む方法を身に付けよう
項目24 リソースはブロックとensureで管理しよう
項目28 モジュール、クラスフックを使いこなそう
項目29 クラスフックからはsuperを呼び出そう
項目30 method_missingではなくdefine_methodを使うようにしよう
項目31 evalのさまざまなバリアントの間の違いを把握しよう
項目32 モンキーパッチの代わりとなるものを検討しよう
項目33 エイリアスチェイニングで書き換えたメソッドを呼び出そう
項目34 Procの項数の違いに対応できるようにすることを検討しよう
項目35 モジュールのprependを使うときには慎重に考えよう
項目47 ループ内ではオブジェクトリテラルを避けよう

全てのイディオムを掲載しておく。

Effective Ruby(長尾高弘 arton PeterJ.Jones)|翔泳社の本

第1章 Rubyに身体を慣らす
項目1 Rubyは何を真と考えているかを正確に理解しよう
項目2 オブジェクトを扱うときにはnilかもしれないということを忘れないようにしよう
項目3 Rubyの暗号めいたPerl風機能を避けよう
項目4 定数がミュータブルなことに注意しよう
項目5 実行時の警告に注意しよう

第2章 クラス、オブジェクト、モジュール
項目6 Rubyが継承階層をどのように組み立てるかを頭に入れよう
項目7 superのふるまいがひと通りではないことに注意しよう
項目8 サブクラスを初期化するときにはsuperを呼び出そう
項目9 Rubyの最悪に紛らわしい構文に注意しよう
項目10 構造化データの表現にはHashではなくStructを使おう
項目11 モジュールにコードをネストして名前空間を作ろう
項目12 さまざまな等値の違いを理解しよう
項目13 ""<=>""とComparableモジュールで比較を実装しよう
項目14 protectedメソッドを使ってプライベートな状態を共有しよう
項目15 クラス変数よりもクラスインスタンス変数を使うようにしよう

第3章 コレクション
項目16 コレクションを書き換える前に引数として渡すコレクションのコピーを作っておこう
項目17 nil、スカラーオブジェクトを配列に変換するには、Arrayメソッドを使おう
項目18 要素が含まれているかどうかの処理を効率よく行うために集合を使うことを検討しよう
項目19 reduceを使ってコレクションを畳み込む方法を身に付けよう
項目20 ハッシュのデフォルト値を利用することを検討しよう
項目21 コレクションクラスからの継承よりも委譲を使うようにしよう。

第4章 例外
項目22 raiseにはただの文字列ではなくカスタム例外を渡そう
項目23 できる限りもっとも対象の狭い例外を処理するようにしよう
項目24 リソースはブロックとensureで管理しよう
項目25 ensure節は最後まで実行して抜けるように作ろう
項目26 retryでは回数の上限を設け、頻度を変化させ、オーディットトレイルを残そう
項目27 スコープから飛び出したいときにはraiseではなくthrowを使おう

第5章 メタプログラミング
項目28 モジュール、クラスフックを使いこなそう
項目29 クラスフックからはsuperを呼び出そう
項目30 method_missingではなくdefine_methodを使うようにしよう
項目31 evalのさまざまなバリアントの間の違いを把握しよう
項目32 モンキーパッチの代わりとなるものを検討しよう
項目33 エイリアスチェイニングで書き換えたメソッドを呼び出そう
項目34 Procの項数の違いに対応できるようにすることを検討しよう
項目35 モジュールのprependを使うときには慎重に考えよう

第6章 テスト
項目36 MiniTest単体テストに慣れよう
項目37 MiniTest仕様テストに慣れよう
項目38 モックオブジェクトで決定論をシミュレートしよう
項目39 効果的なテストを追求しよう

第7章 ツールとライブラリ
項目40 Rubyドキュメントの扱い方を覚えよう
項目41 irbの高度な機能を使えるようになろう
項目42 Bundlerでgemの依存関係を管理しよう
項目43 依存gemのバージョンの上限を指定しよう

第8章 メモリ管理とパフォーマンス
項目44 Rubyのガベージコレクタの動作に慣れよう
項目45 Finalizerでリソースリークを防ぐセーフティネットを作ろう
項目46 Rubyプロファイリングツールを使おう
項目47 ループ内ではオブジェクトリテラルを避けよう
項目48 コストの高い計算をメモ化することを検討しよう

Effective Rubyを読んだので感想を書いてく - WEB SALADの記事も参考になる。

【3-6】「Rubyのしくみ Ruby Under a Microscope」はRubyのインタプリタYARVの仕組みを解説しているディープな本。
普通はこの本のレベルまで理解する必要はないと思うけれど、僕はRubyの定数探索のアルゴリズムと特異メソッドがどうしても腹落ちできなかったが、この本で何となくイメージできた。

たとえば、Rubyのメソッド探索は継承チェーン上に1本でたどる一方、定数探索は最初にレキシカルスコープで検索してから次に継承チェーンをたどる。
よって、定数検索の方がやや複雑だし、ソースを上から読み込むので、そんな挙動になるのかという発見もあった。

たとえば、Rubyのオブジェクトの特異メソッドやクラス本体のクラスメソッドは、特異クラスという別のクラスに存在する。
よって、特異メソッドやクラスメソッドが存在する場所は別のクラス、特異クラスにあるので、特異クラス系列の継承ツリーが別途存在する。

なお、「メタプログラミングRuby第2版」にも特異クラスの絵が掲載されていて詳しく説明してくれているのだが、通常のクラス系列の継承ツリーと、特異クラス系列の継承ツリーを混ぜ込んだ絵で記載しているので、僕には分かりづらかった。
一方、「Rubyのしくみ Ruby Under a Microscope」では、メモリ上にRubyのオブジェクトがどのように配置されるのか、絵が書かれているので、僕には理解しやすかった。

結局、プログラミング言語を理解するには、メモリ上に変数やオブジェクト、配列、ハッシュがどのように配置されるのか、を自分の頭でイメージできなければならないから。

下記の章がお勧めと思う。
Rubyがメモリ上にどのように展開してくれているのかをイメージしやすくなる。

第5章 オブジェクトとクラス
第6章 メソッド探索と定数探索
第8章 Lisp から借用したアイデア
第9章 メタプログラミング

Rubyの定数のお話 | media.growth-and.com

Rubyの定数探索の個人的な謎に迫る - Qiita

「Rubyのしくみ」を読んだ後のRubyの感想: プログラマの思索

【4】Rubyを実際に実務に使う場合は、事実上、Railsをマスターすべきだと思うので、Redmineのソース解読もしながらちょっとずつやっている。

Javaや.NETのWebシステムの開発経験からRailsを見ると、Web開発でまどろっこしい共通処理やWeb特有の処理をRubyのメタプログラミングで上手く隠蔽して、コーディングルールを強制することで数行で書けるようにしている部分はすごいな、と改めて思う。

僕がRailsですごいなと思う点は、特に、JavaScriptとの相性が良い点だ。
Railsが生まれた当初から、prototype.jsやJQueryとの連携はスムーズだったし、JavaScriptを駆使することでWebのUIを豊かにしてくれた。
最近のRailsは、JSライブラリの発展とともに、VueやReactとも親和性が高い。
つまり、クライアントサイドのUI改善も取り込めるので、JavaやPHPなどの他の言語よりもRailsの優位性は高いような気がする。

【5】Rubyを勉強している時の僕の脳みそは、錆びついた機械時計に油を挿しながら、回転させようとしている感覚だった。
こういうことをRubyで実現したいんだ、要件や設計は分かっているのになぜすぐに書けないのか、という苛立ちを感じながらRubyのライブラリを覚えて、動きに慣れようとしていた。

「プログラミングのできる羊とできない山羊を区別する方法」の記事のリンク: プログラマの思索にある「プログラミングができない羊」みたいな地点から登っている感じだった。

でも、初めてのプログラミング言語を習得するには、どんな手順を踏めば良いのか、どういう点に注意すれば習得速度を上げられるか、という感覚はつかめてきた。
今は次のプログラミング言語としてPythonを習得しようとしているが、Rubyの習得経験や、RubyとPythonは考え方が似ているメリットもあって、割と楽に習得できそうな感じ。

結局、プログラミング言語が分かったという感覚になるには、自分の脳みそがコンパイラになりきって、メモリ上に変数やクラスがどのようにロードされて値が変わっていくのか、イメージできる必要がある。

こんな経験は誰でも知っているのだろうが、20代の若い年齢なら簡単であっても、40・50代と年齢を取るごとに、新しいプログラミング言語の習得はどんどん難しくなる。
しかも、プログラミング言語の隆盛は10年おきに移り変わるから、そのたびに以前の言語を捨てながら新しい言語に慣れていかないといけない。
たとえば、FortranやCobolからC/C++/VB、そしてJavaやC#、さらにRubyやPHP、そしてPythonやR、へどんどん変わってきている。
JavaもKotlinで書くのが普通になってきているようだし。

そんな事を考えると、アジャイル開発は常識だ: プログラマの思索にも書いた通りだったのを思い出す。

(引用開始)
ソフトウェア業界の特徴の一つは、一度高い能力が得られてもそれを完全にやり直さねばならない点がある。
Cobolで一流であったとしても、JavaやC#のプログラミングは一流とは限らない。むしろ、オブジェクト指向の概念を知らない可能性も高く、オブジェクト指向の初心者かもしれない。
Javaを知っていても、RubyやiPhoneやAndroidアプリは初心者かもしれない。
様々な言語を学び、共通部分があったとしても、技術の変化によって常に立場は悪くなり、完全に分かったという状態にはならない。
また一から勉強して成長しなければならない。
(引用終了)

最終的には何かアプリが作れればいいな、と思っている。

| | コメント (0)

2019/07/10

前処理大全の良いところ~SQLとRとPythonで対比できる

「前処理大全」の感想をラフなメモ書き。自分のための参考記事をリンクしておく。

【参考】前処理大全[データ分析のためのSQL/R/Python実践テクニック]:書籍案内|技術評論社

『前処理大全』のサンプルコード

Community Blog - 『仕事ではじめる機械学習』&『前処理大全』著者対談(Part 1)

Community Blog - 『仕事ではじめる機械学習』&『前処理大全』著者対談(Part 2)

Community Blog - 『仕事ではじめる機械学習』&『前処理大全』著者対談(Part 3)

Community Blog - 『仕事ではじめる機械学習』&『前処理大全』著者対談(Part 4)

データ分析初心者は「前処理大全」でデータ前処理を学べ | リーマンエンジニアのブログ

前処理大全は機械学習に関わる人の必需品 | Tamanyan.me | たまにゃんのエンジニアブログ

RとSQLを対応付けてみた - あらびき日記

R初心者はこれを見ろ!便利なパッケージまとめ!入門編 - Qiita

dplyrを使いこなす!基礎編 - Qiita

「前処理大全」はサラリと読んだだけのレベル。Rで少しずつ書きながら、こんな使い方をするのか、と初心者レベルから理解している。

R言語は以前からやりたい、と思っていたが、なかなか慣れなかった。SQLは分かるので、「前処理大全」のおかげでSQLと比較することで、R言語の書き方を覚えられる。「前処理大全」には、RよりもSQLの方が短く書ける場合もある、という事例が新鮮だった。

dplyrライブラリのおかげで、SQLのようなデータ操作をUnixパイプみたいに書けるのが快適。データ加工をバラし、試行錯誤しながら、データの特徴を分析できるのが楽しい。ggplotも使えば、データ分析結果をいろんなグラフで表示できるのもいい。

「前処理大全」の面白さは、SQLとRとPythonのプログラムを比較できる点にある。SQLのメリット、Rのメリットがどんな利用シーンであるのかよく分かる。

ちょうど、古代に書かれた聖書で、古代ギリシャ語とラテン語、コプト語を対比した書物みたいな感じ。SQLとRで、ニュアンスの微妙な違いが面白い。

但し、「前処理大全」はあくまでも、機械学習やデータ分析の前処理だけに特化しているので、それだけでは十分でないことは分かっている。本当の面白さはその先にあるから。

| | コメント (0)

2018/09/09

WinSCPでトンネリングする方法のリンク

踏み台サーバーを経由してFTP接続する方法がWinSCPで実現できると分かったので、リンクしておく。
自分が後で参考にするためのリンク。
特に主張なし。

【参考】
WinSCPでトンネリングする方法: 小粋空間

踏み台サーバ経由でWinSCPを使ってSCP接続する方法 | 株式会社ビヨンド

WinSCPで多段階接続をする - 時雨に舞う

外部から踏み台サーバ経由の多段SSH接続をWindowsクライアントから行う | Developers.IO


| | コメント (0)

2017/12/23

仕様書にもExcel脱却が求められている

現代は、タスク管理や障害管理だけでなく、仕様書にもExcel脱却が求められている記事があったのでメモ。
ラフなメモ書き。

【参考1】
エクセルで手順書を作るのはきっとやめた方がいい - Qiita

(引用開始)
ある製品のインストール手順書を作ることになり、参考資料として過去の案件で作ったものをもらったのだが、それはエクセルファイルだった。
どういうものだったかを端的に述べると以下の通り。

目次がない
シート名に番号はついていない
各シートにも番号の記載はない
各シートの中身はスクリーンショットの羅列
スクリーンショットについての説明がほぼない
間違った手順のスクリーンショットも混ざっている
操作の結果を確認する手順が漏れているケースがある

この時点で大分げんなりするが、具体的に辛い点をあげる。

1. 全体像が掴めない
2. 順番に確信が持てない
3. コマンドの内容やインストール先のディレクトリもスクリーンショットに埋まっている
4. インストールがうまくいったかの判断材料がない、それを見つけられない
5. 再利用できない
6. 修正したときに差分がわからない
7. レビューするのが困難
(引用終了)

【1-1】一般に、要件定義書、設計書、テスト仕様書などはExcelで書かれている時がほとんどだ。
しかし、Excelのドキュメントは色んな点で弊害が出てくる。

僕の観点では、Excelファイルは構成管理と相性が悪い、という点が最大の弱点ではないか、とずっと思っている。

まず、GitでExcelを管理してもバイナリファイルは差分が分からないので、履歴管理する効果が薄い。
また、GitHubで管理できないと、コードレビューしにくいし、ユーザからのプルリクエストによるフィードバックも受付できない。
つまり、GitHubがもたらしたソーシャルコーディングという手法を適用できず、アジャイルにドキュメントを修正しにくい。

次に、Excelドキュメントは再利用しにくい。
罫線があったり、画像があったり、レイアウトが特殊だったりすると、修正するだけでかなりの手間がかかる。
特に、シートや節を1個追加すると、インデックスや目次が変わってしまうが、じきに誰も保守しなくなる。
すると、Excel設計書の全体イメージが把握できなくなり、ブラックボックスのような仕様書が残るだけ。

結局、共有ファイルサーバーに、いつ修正されたか分からない状態のExcelドキュメントがたくさん散在することになる。

【参考2】
Atom と PlantUML で快適シーケンス図駆動開発ライフ | Developers.IO

(引用開始)
「認識合わせ」という名目でホワイトボードに図を書いて会話することがよくあります。共通言語で会話してあいまいなところを少なくしたら、マネージャーも安心感がありますし、プログラマも自分がやるべきことに集中できますね。

…3日経ちました。あのとき描かれていたホワイトボードの図のとおりに、実装することになりました。認識の齟齬をなくしてくれた貴重な図です。写真に撮りました。どこに保存してたっけ。やっぱり変更したくなったらどうしましょう。またホワイトボードに書き起こす?DRYじゃないですねえ。

そこで、UML図 が登場します。表現したい図を電子データで作成、保存できて、あとで見るときも役に立ちますね。が、しかし、UML図はそれはそれでやや手間がかかるところもあります。作図を助けてくれるツールやサービスはたくさんありますが、

描画ツールを使いたくない
差分管理ができないのが辛い
メンテするのがいやだ。どこにあるかわかりづらくなる
というのが私の感想です。
(中略)
テキストで書けると差分管理できるようになる点が良いです。履歴が残ります。GitHubの機能が使えます。つまり、変更に対して レビューをしてもらえ、コメントをもらえます。 描画ツールでやろうとするとレビュー方法に工夫が必要ですし、もらったコメントの管理が大変です。GitHubの仕組みに乗せてしまうことでそのあたりの課題が一気に解決できます。

シーケンス図は強い
UMLには種々の図がありますが、こと設計~開発段階においては シーケンス図 が強力です。どのようなコンポーネントがあって、それらがどうやりとりするかを視覚的に捉えることができるためです。

シーケンス図というとオブジェクトがあって、そのオブジェクトのメソッドを実行すると他のオブジェクトが生成される…といったような図をイメージするかもしれませんが、「コミュニケーションをとりつつ進める設計段階」ではもっと大きな粒度、データベースや、外部APIといった粒度をオブジェクトにします。クラスやメソッドレベルのやりとりはコードで十分表現可能 である一方、コンポーネント間のやりとりは外部仕様として日本語ベースになっている ことが多く、後者はたとえ厳密だとしても可読性が低いです。シーケンス図はそれを補完するのに役立ちます。次の図は「ニュースの一覧を外部から取得してクライアントに返すAPI」のシーケンス図です。
(引用終了)

【2-1】設計書にUMLのシーケンス図を書きたい時がある。
なぜなら、たとえば、詳細設計書で仕様の意図を伝えたい時、オフショア開発チームにコンポーネント間の処理のイメージを伝えたい時があるから。
そんな場合、シーケンス図でラフに描くことには意義がある。

しかし、お絵描きするUMLモデリングツールで出力した画像ファイルを設計書に載せると、仕様変更のたびに修正が発生してしまう。
設計書のメンテナンスという作業に、保守PJではかなりの工数を費やされている場合が多いのではないか。

ここでも、たとえば、UMLのシーケンス図をplantUMLでテキストで残し、GitHubで管理し、設計レビューで使う、という運用が紹介されている。
UMLで描いた設計の絵はテキストファイルで保持できるなら、GitHubに載せることで、プログラミングの時と同じような効果が得られる。

【2-2】下記の記事では、設計書は全てテキストで書き切る、という方法が紹介されている。

AsciiDoc と PlantUML と mermaid.js で素敵なテキストベース仕様書ライフ

設計書そのものもMarkdownやAsciiDocでテキストで保持しておけば、Jenkinsで定期的にビルドして最新版のドキュメントを出力する、という手法も採用できる。
つまり、設計書もプログラミングと同様に、最近の開発スタイルを適用できるはず。

Redmineに作業内容をチケット起票
→設計書をExcelでなくテキストで作成
→Gitにコミット
→GitHubやGitlabで設計レビュー、再修正してGitにコミット
→Jenkinsで定期的にビルド
→納品時に、タグ付けした版を成果物として納品

「設計書は全てテキストで書き切る」ことにより、設計書も構成管理の配下になり、アジャイル開発の各種プラクティスが適用できるし、その恩恵も受けられる。

また、チケット駆動開発のメリットであるトレーサビリティを設計書の変更管理に利用できるようになる。
そうすれば、システム保守での元々の要件の調査、仕様変更の影響範囲の調査に大いに役立つはず。

【3】ちなみに、Redmineでもmermaidやplantumlのプラグインが提供されている。
RedmineのWikiに、設計概要やノウハウを集約できるので、便利になるはず。

Redmine Mermaid Macro Plugin

Mermaid Macro - Plugins - Redmine

「mermaidプラグインで始める構成図管理」 20171117 redminetokyo13

RedmineでPlantUMLを使う事例: プログラマの思索

Redmine で技術仕様書を書こう | Aiming 開発者ブログ

plantuml - Plugins - Redmine

【4】しかし、仕様書をExcelでなくテキストで全て書いて、ソース管理と同様にGitの構成管理に置くというやり方は、まだ試行錯誤している所だろう。
たくさんの課題がまだ残っているだろうが、いわゆる上流工程でも下流工程と同様に開発プロセスもIT化していくべきだ、という方向性へ進化せざるを得ないと思う。

【追記】
ソフトウェア開発の設計書のExcelテンプレートを公開した記事について、数多くのはてなブックマークが寄せられていた。
ここにも、上記の問題点が背後にあるのだろう。

はてなブックマーク - 無料のシステム開発テンプレート集(Excel版): ある SE のつぶやき

akipiiさんのツイート: "皆苦労してるんだな笑。RT @mandamgame: RedmineのAPI叩いて未完了チケットを表にするExcelください。 / 他154コメント https://t.co/jXdGcJ3iFe “無料のシステム開発テンプレート集(Excel版): ある SE のつぶやき”… https://t.co/MBWCoh8mBQ"

akipiiさんのツイート: "@MadoWindahead @mandamgame いえいえ、Excel設計書のテンプレートなので、PJ毎の設計書が作られるため構成管理すべき対象になります。今の時代は、plantUMLでmarkdown形式でクラス図やシーケンス図で詳細設計書を書いたり、ドキュメントは全てmarkdownで書いた方がGitで管理しやすい、と思います https://t.co/UpnoEEDcbj"

| | コメント (0)

2017/05/05

ソフトウェアの複雑性は本質的な性質であって偶有的なものではない

「過剰と破壊の経済学-「ムーアの法則」で何が変わるのか」を気軽に読んでいたら、ブルックスの人月の神話の一節が書かれていて、今頃になって、すごく腑に落ちたのでメモ。
ブルックスの人月の神話の文章のうち、自分が理解できたことを、ラフなメモ書き。
以下は書きかけ。

【参考】
第0回:人月の神話とはなんなのか?(解説編)|本気で読み解く”人月の神話” | GiXo Ltd.

第2回:銀の弾は無いけど、”銃”はあるよね|本気で読み解く”人月の神話”(第16章) | GiXo Ltd.

ソフトウェア開発とは、現実世界の複雑さをプログラムコードの難しさに置き換える作業だ - セカイノカタチ

ソフトウェア開発でよく言われる「銀の弾丸など無い」とはどういう意味なのか本を読んでみた。 - 感謝のプログラミング 10000時間

【1】ソフトウェアの複雑性は本質的な性質であって偶有的なものではない。

「過剰と破壊の経済学-「ムーアの法則」で何が変わるのか」の内容自体は10年以上前のWebやIT業界の話が多く、内容も古くなっているので、新たな知見が得られるという感覚はしない。
しかし、「過剰と破壊の経済学-「ムーアの法則」で何が変わるのか」の中に、「ソフトウェアの複雑性は本質的な性質であって偶有的なものではない」という言葉があって、すごくしびれた。

(引用開始)
ソフトウェアの複雑性は本質的な性質であって偶有的なものではない。
したがって、複雑性を取り去ったソフトウェアの実体の記述は、しばしばその本質も取り去ることになる。
数学や物理学は、複雑な現象を単純化したモデルを構成し、そのモデルからある性質を引き出し、実験的にその性質を証明することで、3世紀にわたって偉大な進歩を遂げた。
この方法でうまくいったのは、モデルで無視された複雑性が現象の本質的な性質ではなかったからだ。
複雑性が本質である場合には、この方法は使えない。
(引用終了)

上記の内容は、ブルックスの「人月の神話」の一節そのまま。
なぜ自分がすごく衝撃を受けたのか、考えてみると、ソフトウェア開発の本質に触れているものだから。
たぶん、僕の心のなかにある、ソフトウェアに対する楽しさだけでなく、ソフトウェアへの憎しみというか、なぜこう思い通りにソフトウェア開発をコントロール出来ないのか、という腹立たしさに触れている気がしたから。

「偶有的」という言葉も引っかかる。
この言葉は、古代ギリシャのアリストテレスの哲学から引用したものらしい。

(引用開始)
アリストテレスに従って、難しさを本質的なものと偶有的なものに分けて考えてみよう。
ここで、本質的な複雑さとは、ソフトウェアの性質に固有な困難のことであり、偶有的難しさとは、目下の生産にはつきまとうが本来備わっているものではない困難のことである。
(引用終了)

自然科学、特に数学や物理学では、できるだけ単純なモデルを作り、そこから演繹される性質や定理を証明することで、自然現象を多面的に分析しようとする。
複雑なものを複雑なまま捉えるのではなく、理想的な単純なモデルに純粋化して、人間の思考に耐えられるレベルにして、数多くの観点で徹底的に分析するのが自然科学のやり方。
シンプルなモデルを「徹底的に」分析し尽くして、全ての特徴を洗い出し、全てを因果関係や演繹でまとめ上げて一つの理論体系にするのが自然科学のやり方。

すると、シンプルなモデルをどのように事前設定するか、どのパラメータを重視して選択しておくか、というのが重要になる。
その部分が、科学者の腕の見せ所。

たとえば、物理学では、理想気体みたいに、現実から離れるけれど、シンプルなモデルを設定することで、計算や実験を扱いやすくするモデル作りは一般的だ。
熱力学、相対性理論、量子力学など、色んな分野の物理学でもその手法を用いている。

物理学は一つの認識論: プログラマの思索

数学でも、一流の数学者は、自分で理論を打ち立てたい時、最も組合せの少ない公理や公準を直感的に選んで、そこから矛盾が生じないように設定しておく。
そこから、「誰々の定理」のような重要な結果を導き出す。
一流の数学者がすごいのは、最も組合せの少ない公理を直感的に把握できること、そして、重要な定理を導く時に、ロジックの穴になりそうな難しい場所を事前に察知して、それをくぐり抜けるために、あらかじめ「誰々の補題」みたいな補助的な公式を用意しておくのが上手い点。

技術の背後に数学の理論があると廃れない: プログラマの思索

数学や物理は背景にある思想を知らなければ理解できない: プログラマの思索

このやり方がすごく成果を上げているので、人文科学や社会科学でもそのやり方を真似ているように思える。
特に、経済学は典型的だろう。
マクロ経済学やミクロ経済学みたいに、人間は合理的に行動する、とか、市場の価格は恣意的な手段で決めても長続きせず、神の手(つまりは市場原理)で決まる、みたいに、現実とかけ離れた仮定をおいて、数多くの経済モデルを作り、そこから重要な経済学の定理を導き出す。
単純な経済モデルから得られた経済学の定理で現実に通用する場面が過去にあったから、経済のグローバル化が世間に言われ始めてから、世の中の経済事象は、市場原理で決まる、いや決めるべきだ、みたいな論調が多い気がする。

経済数学の直観的方法の感想: プログラマの思索

「推計学のすすめ」「経済数学の直観的方法~確率統計編」の感想: プログラマの思索

しかし、ブルックスの「人月の神話」では、ソフトウェアにはそのやり方が通用しない、という指摘をしている。
「ソフトウェアの複雑性は本質的な性質であって偶有的なものではない」からだ。
つまり、複雑性を排除したソフトウェアは、ソフトウェアの本質を意味しないからだ。

【2】ソフトウェアの本質的な複雑さと、偶有的な複雑さの違いは何か?
ソフトウェアの本質的な複雑さは、リーマンの法則そのものを指すと思う。

リーマンの法則~ソフトウェアもエントロピー増大の法則を避けられない: プログラマの思索

リーマンの第1法則
 使われるシステムは変化する。
リーマンの第2法則
 進化するシステムは複雑性を減らす取り組みをしない限り、システムの複雑性が増す。
リーマンの第3法則
 システムの進化はフィードバックプロセスによって決まる。

(引用開始)
レーマンとベラディは、大規模なオペレーティングシステムのリリースについて、継続してその変遷を研究してきた。
そこで分かったことは、モジュールの総数はリリース番号とともに線形に増加するのに対し、影響を受けるモジュールの数はリリース番号に対し指数的に増加するということだ。
(中略)
システムプログラムの作成は、エントロピーを減らす仮定だから、本来は準安定なものである。
他方、プログラムメンテナンスはエントロピーが増加する過程であり、どんなに器用に行なっても、できるのはシステムが修正不能な陳腐化へと沈んでいくのを遅らせることだけである。
(引用終了)

(引用開始)
ソフトウェア製品開発に関する古典的問題の多くは、その本質的な複雑性と、ソフトウェアの大きさに従ってその複雑性が非線形に増大することに由来している。
(引用終了)

この文章を読んで思い出すのは、ケント・ベックがXPを生み出した経緯のことだ。
ケント・ベックは、ソフトウェア工学の授業で習った、リリース総数が増大するにつれてソフトウェアの複雑度や変更コストが増大していく経験則に対して、異議を唱えた。
時間が進むに連れて、この曲線を頭打ちにできるような開発プロセスはないのか、と。

- eXtreme Programmingの魅力を探る オブジェクト倶楽部

(引用開始)
「変化ヲ抱擁セヨ」
この呪文めいた言葉は,Kent Beck による本の副題として掲げられている. 時間を横軸に,ソフトウェアの変更にかかるコストを縦軸にプロットする.
この「時間-変更コスト」曲線は極端な右上がりになると信じられて来た(図左).
すなわち,要求分析,設計,実装,テスト,保守,と時間が進むにつれ, 変更にかかるコストが増大するというのだ.
現在までのソフトウェア開発プロセスは,この仮定上の議論が多数 だったのである.
XP はこの曲線を平坦にできるのではないか, また,そうできたとしたら,全く違った方針でプロジェクトに立ち 向かえるのではないか,という挑戦をしている(図右)
(引用終了)

こういう素朴な問題意識はすごく重要だと思う。
XPがその理想を本当に実現したのかどうか、は検証がいると思うが、そういう背景を元にアジャイル開発のプラクティスが生まれたことは、アジャイル開発が従来のソフトウェア工学と対立しがちに見える傾向を示唆しているように思える。

ちなみに、上記の第1版の「XPエクストリーム・プログラミング入門―ソフトウェア開発の究極の手法」に、上記の「従来のソフトウェア工学が提唱しているソフトウェア複雑性へのXPの果敢な挑戦」の文章と図はあるのに、第2版の「エクストリームプログラミング」から削られていることだ。
とても残念。
この部分がXPにとって一番重要な主張なのに。

【3】コードクローンと再利用性。

(引用開始)
ソフトウェア実体の本質とは、データセットやデータ項目間の関係、アルゴリズムや機能呼び出しなどが組み合わさったコンセプトで構成されたものである。
この本質は、同じ概念構造体が多くの異なる表現で表されるという点で抽象的である。
それにもかかわらず、非常に正確で十分に詳細なものである。
(引用終了)

コードクローンとは、同一アルゴリズムを各プログラマが別々の実装したプログラムのことだ。
上記は、ソフトウェアの複雑性が増大しがちな理由の一つは、コードクローンが大量に発生しがちである、と言う点を示唆していると思う。

ソフトウェア工学の論文を見ていると、コードクローンのメトリクス採取の記事が割と多い。
その理由は、コードクローンを減らす方がソフトウェアの複雑性が減るので、良い、という主張が隠れているのではないか。

では、なぜコードクローンは良くないのか?

(引用開始)
ソフトウェア実体は、どの2つの部分をとっても似ることがないので、大きさの割にはおそらく他のどの人工構造物よりも複雑なものだ。
似通っている部分があれば、2つの類似部分を1つにする。
この点において、ソフトウェアシステムは、重複要素(部品)が豊富なコンピュータやビルあるいは自動車などとは全く異なっている。
(引用終了)

その理由は、ソフトウェアの再利用が進まないからだ。
たとえば、自動車やパソコン、スマートフォンのような工業製品は、再利用可能な汎用部品を組み立てる手法と大量生産することを組合せることで、規模の経済を生かし、経験曲線効果を生かして、1個当りの製造コストを劇的に減らす。
しかし、この「規模の経済」「経験曲線効果」というコストメリットを享受しうる生産手法がソフトウェア開発には全くといっていいほど通用しない。

ソフトウェアを部品化して、スマートフォンみたいに部品を組み立てるように製造したい、と考えて、CORBAとかEJBのようなコンポーネント駆動開発、製品ファミリー群の製品開発手法であるソフトウェアプロダクトラインとか色々考えられたけれど、どれも実用的ではない。

ソフトウェア部品化の幻想: プログラマの思索

ソフトウェアプロダクトラインが解決しようとするもの~品質と再利用: プログラマの思索

だから、多額の資金を設備投資に投入して、最新の機械で汎用部品を組合せて大量生産する生産手法がソフトウェア開発には馴染まない。
ソフトウェア開発は徹頭徹尾、経験曲線効果すらも有効でない労働集約的な生産手法に似ているように思える。

【4】ソフトウェアの本質的な複雑性とは、同調性、可変性、不可視性。

【4-1】同調性は、リーマンの言う組み込まれた(Embeded)プログラム、を連想する。

「ソフトウェア・グラフィティ」の感想: プログラマの思索

(引用開始)
支配しなければならない複雑性の多くは気まぐれによるものだ。
インターフェイスを人間の社会制度やシステムに適合させるべく、いわば是非もなくそれらによって強制されているからである。
(引用終了)

最近、業務システムとかERPに僕自身が少し興味をなくしているのは、システム化したい業務そのものが元々複雑過ぎて、それを整理しようと言うよりも、現実の業務をいかに忠実にシステム化するかに注力する案件の方が多いからだ。
元々の業務が、日本的な複雑な組織体制を元に作られていれば、複雑なのは当たり前であり、それを忠実にシステム化するなら、複雑怪奇なままだ。
日本では、ERPをBPRとして捉えるよりも、自分達の業務中心に考えすぎているために、システムも複雑怪奇になりやすいような気がしている。

【4-2】可変性は、ソフトウェア品質の移植性や保守性を連想する。

アジャイル開発が重視する品質特性~保守性と移植性: プログラマの思索

(引用開始)
ソフトウェア実体は、つねに変更という圧力にさらされている。
(引用終了)

XPの言う「変化を抱擁せよ」と同じ。
ソフトウェアにとって、VerUpは宿命であり、常に変化が内在している。
ソフトウェアは変化しない固体として存在し得ない。

(引用開始)
純粋な思考の産物であってきわめて融通性に富んでいるので、ソフトウェアがより簡単に変更できるということもある。
ビルも現実には変更されるものだが、だれもが了解しているように、変更コストの高さが思いつきで変更しようとする者の気をくじく働きをしている。
(引用終了)

ソフトウェアに、仕様変更という名の保守はつきものだ。
それは簡単にできるように思えるから、簡単にソフトウェアに手を入れて、潜在バクを埋め込んでしまう。
ソフトウェア品質特性のうちの保守性を連想させる。

(引用開始)
大当たりしたソフトウェアはまずたいてい、すべて変更される。
あるソフトウェア製品が役立つと分かると、人々はもともと処理対象としていた領域ぎりぎりもしくはその領域を越えるような新しい使い方を試してみようとする。
主として、拡張機能のために変更して欲しいという圧力は、基本機能が気に入っていて新しい使い方を考えだす利用者から出される。
(引用終了)

これは、たとえば、Redmineが当初のバグ管理の使い方から、タスク管理、そして、アジャイル開発やWF型開発、さらには、事務処理ワークフロー、ハードウェア資産管理システムへ使い道がどんどん広がっていった事例を連想させる。
本来想定しなかった使い方が一般的になってしまい、その使い方をさらに使いやすくしたり、機能改善することで、ソフトウェアの複雑性がどんどん膨張する。
あらゆるソフトウェアは機能追加という変化にさらされている。

(引用開始)
大当たりしたソフトウェアは最初に書かれた対象である機械機器の通常の寿命よりも長く使用され続ける。
要するに、ソフトウェア製品はアプリケーションや利用者、慣習および機械機器といった文化的マトリックスにすっかりはめこまれているのだ。
そしてそれらは絶えず変化し続けるものであり、その変化がソフトウェア製品に容赦なく変更を強制するのである。
(引用終了)

たとえば、OSやDBやミドルウェアのバージョンアップとか。
あるいは、サーバー本体のリプレースとか。
たとえば、WindowsXP廃棄対応、WindowsServerのリプレース、OracleのVerUp、RailsのVerUpとか、iOSやAndroidOSのVerUpとか、色々思い出す。
つまり、ソフトウェア品質特性の移植性を連想させる。

こういうミドルウェアやOSのVerUpに伴うプログラム変更作業は、とてもしんどいものだ、と開発者なら誰でも知っている。
こういうつまらない開発基盤のVerUp作業は、ソフトウェアの外にある外部環境の変化によって生じるものであり、避けることは出来ない。

【4-3】不可視性は、ソフトウェア設計の難しさを連想する。

(引用開始)
ソフトウェアの構造を制限したり単純化したりすることは進歩したにもかかわらず、その構造は本質的に視覚化できないままになっている。
そのため強力な概念上のツールを作る意欲を阻害している。
その欠落は1人の人間の頭の中のデザインプロセスを妨げるばかりでなく、複数の人間の間でのコミュニケーションもひどく妨害する。
(引用終了)

UMLやDOAは、ソフトウェア構造を視覚化する問題を解決しようと試みていた。
SySMLもその流れだろう。

複雑性をコントロールするための設計技法は、歴史上いくつか考えれてきた。

たとえば、Nティア設計。
つまり、レイヤ化。

another level of indirection
「もう一段の間接参照」を導入すると、コンピュータのほとんどの問題は解決できる。

NFuji's Café: 「Beautiful Code」を読む(中)

ポインタを制する者はプログラミングを制する: プログラマの思索

MVCモデル、通信プロトコルの7層モデルもそういう考え方だろう。

他に、渡部幸三さんの観点でのDOAでは、業務・機能・データの3層構造の業務システムにおいて、業務レイヤとデータモデルのレイヤに複雑性を押しこんで、機能レイヤは複雑性をできるだけ減らす設計が良い、と提唱していた。
すなわち、機能レイヤはまさにプログラミングレベルなので、その部分の複雑性はできるだけ減らして保守性を高めようとする考え方。
つまり、複雑性というエントロピーは一定で変わらないと仮定した場合、人が携わる業務レイヤと、データモデルのレイヤに複雑性を落としこんで、複雑性をコントロールしようとするわけだ。

だが、これらの手法で、ソフトウェア本来の複雑性が本質的に解決されたのか、と問うてみると、正直分からない。

【5】一方、ソフトウェアの偶有的な複雑さは個別撃破している。

「高水準言語」は、たとえば、VBよりもRuby。
たとえば、VBはListやHashなどの基本ライブラリのAPIが非常に不足していて使いにくい。
たとえば、Rubyなら、そういう低レベルなライブラリは非常にAPIが揃っていて、VBよりも1行で書ける。
つまり、複雑性を軽減している。

「タイムシェアリング」は、たとえば、コンパイラ言語よりもインタプリタ言語、継続的ビルド管理、構成管理を指すのかな。

(引用開始)
考えていた内容をすっかりというわけではないが些細な点でどうしても忘れてしまう。
(引用終了)

この部分は、まさにソース管理、構成管理を連想させる。
たとえば、CVS、Subversion、Gitに至るまでの構成管理ツールの歴史を振り返れば、ソフトウェア開発プロセスにおけるブランチ管理、マージなどの作業の複雑性は軽減されている。

「統一されたプログラミング環境」はたとえば、VisualStudioやEclipse、IntelliJとか。

つまり、ソフトウェアを開発する作業そのものが生じる複雑性は、今までの歴史で生み出された技術によって、多少は軽減されてきた。
しかし、だからと言って、ソフトウェアの本質的な複雑性を攻略できたわけではない。
あくまでも、以前よりも大きい複雑なソフトウェアをコントロールできるようになった、というだけだ。

| | コメント (0)

より以前の記事一覧