ここぞというときの集中力Upのために、ヘッドフォンで音楽を聴きながらプログラミングしましょう

仕事や趣味でプログラミングしたり技術書を読みながら勉強したりする際には、言うまでもなく集中力を高めて維持することが大切ですね。職業プログラマーに必要な集中力ということには少なくとも二つの意味があるとは思いますが、

いずれにしても、自分の場合は寝不足だったり、周りの雑音で気が散ったりしてコンディションが悪い時にはあまり集中できずに、圧倒的に作業効率が下がってしまいます。逆に、調子よく集中できた時には時間がたつのも忘れて一気に仕事を片付けることができます。
もちろん、プログラミングで集中力を高めるためには、日頃から規則正しい睡眠や食事などが欠かせませんが、ここぞという時に一人で集中するにはヘッドフォンで音楽を聴くのが個人的には非常に効果的な手段だと思っています。
客先常駐の場合は、常駐先の会社の文化によってはヘッドフォンで音楽を聴きながら作業をすることを禁止しているところもあるかもしれませんが、幸運なことに自分のチームではOKなので、本当に一人で集中して考えたいときにはヘッドフォンを利用しています。もちろん、ヘッドフォンにはチーム間のコミュニケーションを阻害するという弊害もあって、周りの人に質問しづらくなってしまうという問題があるのですが、一日の作業のうちで集中する時間を区切って利用すればよいのではないでしょうか。
音楽を聴きながらプログラミングする際の問題は、どのような音楽が集中に適するかということですね。一般的には歌詞のない音楽でモーツァルトなどのクラシック音楽などがよいとよく言われますが、もちろん、これには好みによって個人差があると思いますし、人によってはクラシックはかえって心地よくて眠くなるという人もいるかもしれません。
私の場合はずいぶん以前からいわゆる「集中力Upのための音楽」というちょっと怪しげなジャンルの音楽に非常に興味があって、実際仕事や勉強でいろいろと活用しています。

Focus CD (フォーカス CD)

Focus CD (フォーカス CD)

たとえば、以上のCDは雨の音がひたすら聞こえるだけなのですが、左右の耳から周波数の異なる音を同時に聴くことでいわゆるバイノーラルビートと呼ばれる効果で脳の集中力が活性化するそうです。Amazonのレビューでも高評価なので試してみてはいかがでしょうか。このCDの製造元の説明は以下にあります。
immramainstitute.com
そのほか、同様のバイノーラルビートを活用した音楽でヘミシンクと呼ばれるシリーズのタイトルはいくつか利用していますが、個人的にはかなりおすすめです。(以下で部分的に視聴できます。)


インディゴ : Indigo for Quantum Focus [ヘミシンク]

インディゴ : Indigo for Quantum Focus [ヘミシンク]

コンセントレーション : Concentration [ヘミシンク]

コンセントレーション : Concentration [ヘミシンク]

アインシュタインズ ドリーム : Einstein's Dream [ヘミシンク]

アインシュタインズ ドリーム : Einstein's Dream [ヘミシンク]

イルミネーション フォア ピーク パフォーマンス : Illumination for Peak Performance [ヘミシンク]

イルミネーション フォア ピーク パフォーマンス : Illumination for Peak Performance [ヘミシンク]

Remembrance [ヘミシンク]

Remembrance [ヘミシンク]

ブレークスルー : Breakthrough [ヘミシンク]

ブレークスルー : Breakthrough [ヘミシンク]

以下は、ブレインシンクと呼ばれる別のシリーズで、ヘミシンクと同様に集中力や記憶の向上に役立つとされているタイトルがあります。
High Focus: Activate Lucid Thinking (Brain Sync Audios)

High Focus: Activate Lucid Thinking (Brain Sync Audios)

Brain Power

Brain Power

なお、これらの音楽は人によっては非常に深い集中状態をもたらすため、逆に外界に対する反応が鈍くなってしまうことがあり、自動車で運転中などには絶対に聴かないようにとの注意書きがあります。

Javaの型パラメーターに対してstaticメソッドを呼び出した場合の挙動

以前にJavaの配列関連で調べたことがあったのですが、Javaの総称型は型消去によって直感的でない挙動をする場合があります。
Java言語のClassクラスが持つちょっと不思議な性質について - 達人プログラマーを目指して
Java5の型システムを理解するにはリフレクションAPIを使ってみるのが最短の近道になる - 達人プログラマーを目指して
特に、総称型の型パラメーターTについては以下はコンパイルできないという制約があります。

  • new T()
  • new T[配列サイズ]
  • catch (T ...
  • extends T
  • T.class
  • instanceof T

また、staticメソッドやstatic初期化ブロック内でクラスの型パラメータを使えないという制約もあります。
AngelikaLanger.com - Java Generics FAQs - Type Parameters - Angelika Langer Training/Consulting
このような制約は型Tが実際にはコンパイル時に消去されるということを考えれば納得のできるものです。これらの制約は初心者だけでなく、C++C#Haskellといった言語を使いこなす上級者であっても勘違いしやすいところですね。
それで、最近ちょっと話題になって気づいたのですが、実は型パラメーターTに対してstaticメンバのアクセスはどうなるのかという点が実は盲点で、自分もちょっと勘違いしていました。当然new Tが認められていないのだから、T.staticメンバという形式の呼び出しはコンパイルエラーなのだと考えていたのですが、実際に以下のコードを実行してみるとわかるように、Tは単に消去型として処理されるのですね。だから、型の上限が設定されていた場合はその上限の型のstaticメンバを呼び出すことができてしまうようです。

class Parent {
    public static String field = "Parent";
    
    public static void method() {
        System.out.println("Parent");
    }
}

class Child extends Parent {
    public static String field = "Child";

    public static void method() {
        System.out.println("Child");
    }
}

public class Tester<T extends Parent> {

    public void test() {
        T.method(); 
        System.out.println(T.field);
    }

    public static void main(String[] args) {
        Tester<Child> child = new Tester<>();
        child.test();
        // Parent
        // Parent
    }
}

実際にはTの消去型は上限のParentなのでTesterクラスは型消去されると以下と等価になります。

public class Tester {

    public void test() {
        Parent.method(); 
        System.out.println(Parent.field);
    }

    public static void main(String[] args) {
        Tester child = new Tester();
        child.test();
        // Parent
        // Parent
    }
}

そのように考えれば、このように実際にバインドされたChildでなく「Parent」が表示されてしまうのも納得がいきますが、かなり直感に反する気もします。TesterのようにChild型がTにバインドされているのだから、Tのstaticメンバーの呼び出しはChild側にバインドされるのが自然に思えます。
どうして、Javaではこのように型パラメーターに対するstaticメンバーの呼び出しを認めているのでしょうか。newの場合と同じ理屈ならコンパイルエラーにもできたはずなのですけれどね。

(追記)
ちなみに、staticでない場合を試してみました。

class Parent {
    public String field = "Parent";
    
    public void method() {
        System.out.println("Parent");
    }
}

class Child extends Parent {
    public String field = "Child";

    public void method() {
        System.out.println("Child");
    }
}

public class Tester<T extends Parent> {

    public void test(T instance) {
        instance.method();
        System.out.println(instance.field);
    }

    public static void main(String[] args) {
        Tester<Child> child = new Tester<>();
        child.test(new Child());
        // Child
        // Parent
    }
}

new T()はコンパイルできないため、外部でChildをインスタンス化して渡すようにしています。普通のインスタンスメソッドの場合は、
いまさらですが、職業Javaプログラマーなら理解しておいてほしい「継承」の意味について - 達人プログラマーを目指して
で説明したとおり、ポリモーフィズムがあるので、意図したとおりChildの方のメソッドが呼び出されていることが確認できます。しかし、publicフィールドの場合は、staticメソッドと同様にポリモーフィズムがないためParentの側が表示されました。
ブクマのコメントにもありましたが、教訓としては、インスタンスメソッド以外サブクラスで「オーバーライド」するのは避けた方が良いということですね。

日本における初の解説書であるJenkins実践入門を送っていただきました

先日、技術評論社の傳智之さん(@dentomo)より、Jenkins実践入門を献本していただきました。どうも、ありがとうございました。

Jenkins実践入門 ?ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)

Jenkins実践入門 ?ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)

既に、Jenkins(Hudson)については、開発プロセスを自動化する継続的インテグレーションに欠かせないツールとして、日本でも非常に人気高いツールとなっており、また、雑誌やインターネットの記事でも今まで時々特集が組まれてきたと思います。
WEB+DB PRESS 総集編 [Vol.1?60]

WEB+DB PRESS 総集編 [Vol.1?60]

特に、作成者の川口耕介さん(@kohsukekawa)が日本人であるということもあって、日本語へのローカライゼーションやコミュニティー活動(プラグイン開発、勉強会など)が他の国と比べても活発なように感じます。実際、今回監修を担当された川口さん自身がまえがきの冒頭で、

Jenkinsは、世界中で広く使われている継続的インテグレーションサーバです。拡張性が高く、日本語化が進んでおり、活発なコミュニティーもあるお陰で、日本でもJenkinsの認知度は高いと思っています。

と書かれているように、世界に比べても日本はJenkins先進国と言えるのではないかとさえ思えます。ただし、その直後に書かれているように

しかし、実際に現場に適用しようと思った時に、拡張性・自由度の高さがかえって仇になって、「どうしたらいいかわかならい」という声もよく耳にします。ちょうど「レゴブロックが箱いっぱいにあるけれども、どうやったら家を作れるかわからない」というような状態です。

という言葉が、現状の状態を非常によく表現していると感じました。先進的なツールに対する積極的なコミュニティー活動が行われている一方で、多くの現場ではなかなか思うように普及が進まないというギャップは実際に多くの方が感じているのではないでしょうか。そのような状況にあって、本書のような気軽に読めるJenkinsの入門書が出版されたことは、このギャップを急速に埋める意味でも非常に大きな意味を持っていると思います。

本書は12個の章に分けて実践的なJenkinsの活用方法が解説されていますが、大きく3つに分けると

  • JenkinsやCIのコンセプトに対する入門(1章〜3章)
  • 実際の開発プロジェクトで必要な実践的な解説(4章〜8章)
    • JUnitテストレポートの組み込み
    • テストカバレッジレポートの組み込み
    • 自動コードインスペクション
  • より高度な話題の紹介(9章〜12章)
    • ユーザー管理
    • マルチプロジェクト依存関係設定
    • 分散ビルド
    • プラグインの利用、開発

のように大きく3つの部から構成されているように感じました。全体的に画面キャプチャを多用して、非常に丁寧に解説しており、本書を読み進めるためには高度なプログラミングのスキルは一切必要ありません。したがって、特に前半部分は非プログラマーのマネージャーやリーダーの方が、組織に初めてJenkinsを導入する際にも大いに参考になると思われます。一方で、既にJenkinsを使い込んでいる人にとっても、特に後半に書かれている、分散ビルドの考え方やプラグイン開発の方法については、十分に読み応えのある内容になっているのではないかと感じました。
入門書としては必要十分な適切な範囲を扱っていると思いますが、さらに、個人的に本書の内容に補うところがあるとすれば、

  • Mavenプロジェクトなどのマルチプロジェクトの構成方法(外部ライブラリーの依存管理)
  • テスト環境、プロダクション環境などのビルド対象環境の使い分けテクニック
  • Groovyなどのスクリプトを使った運用管理の自動化
  • Cloudbeeなどのクラウド開発環境や仮想環境でのJenkinsの活用方法

などでしょうか。これらについては、さらに、続編が期待されるところではありますが、本書を読み終えた方であれば、ネット上の情報で十分に自力で調べられるようになるかもしれません。もちろん、実際にアジャイルな開発環境を構築するためには、本書で紹介されているCI環境に加えて、ソースコードの構成管理ツールや、バグトラッキングシステム(BTS)についても調査する必要があるでしょう。
さて、私自身は、継続的インテグレーションなどのプラクティスはCruiseControlなどの別のツールを利用して以前から部分的に試みたことはありましたが、2008年の終わりごろから(Jenkinsの前身となる)Hudsonを使い始めました。20個くらいのサブプロジェクトからなる、それなりに大きな規模のプロジェクトのビルドをHudsonを使って自動化し、毎週定期的にテスト環境にリリースするというような、比較的ペースの速いプロジェクトで使ったことがあります。
ビルドシステム構築スキルの重要性 - 達人プログラマーを目指して
この時は、まだこのような解説書もなく、いろいろと手さぐりな状況でしたが、直感的なユーザーインターフェースのおかげもあり、ボタン一つで複数の環境用のビルドを自動実行するというシステムを作り上げることができました。最初のリリース時にはビルドからテスト環境までリリースするのに多くの手動作業が入っていたため、半日くらい時間を要したのですが、毎週リリースごとに徐々に手順を改良し、最終的にはビルド自体は20分もかからないくらいまで効率化できました。当時、このような入門書があったらどんなにかよかったのにと思いますね。
なお、以前に
SIerにはコード記述の自動化からビルド・デリバリの自動化へのトレンドの変化を理解してほしい - 達人プログラマーを目指して
で、一般にSIerはビルドを自動化していないというような誤解を与えかねない書き方をしてしまったのですが、なんと、本書の著者は全員NTTデータで研究をされている方々のようです。残念ながら、多くの現場では研究成果を浸透させるということが難しいという状況もあるのかもしれませんが、SIerでも先進的な取り組みをされているところがあるのですね。実際に、かなり前に以下のような記事を書いたことを思い出したのですが
もしSIerがまともなエンジニアリングの会社だったとしたらどんな仕事が考えられるか? - 達人プログラマーを目指して
本来SIerというのは情報システム構築の専門家集団であって、むしろ、率先的にJenkinsのような仕掛けを導入することを提案すべきだと思います。実際に、自分の今の会社もそうなのですが、新しい機能を頻繁にリリースするためには、こうしたビルドの自動化、デプロイのパイプライン構築が欠かせません。ただし、一般のユーザー企業でこうした専門家集団を育てて確保することは容易ではありません。ThoughtWorks社のようにSIerが率先してこうした部分の研究を行い、ユーザー企業に対して提案できるようになるというのはSIerが目指すべきあるべき方向の一つなのではないかと感じました。

転職して感じたウォーターフォール文化とアジャイル文化の違いについて

今月から新しい会社に転職して、あっという間に半月が過ぎてしまいました。いろいろな会社の規則や、開発環境、フレームワーク、仕事の進め方など、とにかくたくさんのことを短期間で詰め込む必要があり、もともと想定していたことではありますが自分としてはかなりたいへんでした。
やはり、自分としては、外資系の会社で英語でのコミュニケーションが必要となるということが、最も気がかりなことでした。実際、初日の歓迎ランチはいきなり名前もわからない多くの外国人に囲まれる状況でしたし、電話会議を使って中国やアメリカのチームと一緒に行う日々の進捗ミーティングも英語で行われています。自分としては、特に、リスニングが苦手ということもあり、いまだに完全に会話についていくのが困難なところはありますが、同僚やマネージャーもみんなすごく親切に教えてくれるので安心しました。私は新しい環境に慣れるのに結構時間がかかる方なので、まだまだ完全に新しい職場の文化に適応するというところまではいかないのですが、徐々に仕事のやり方を覚えて、チームの一員として頼られる存在となれるよう努力していきたいですね。
ということで、実はまだ新しい会社の文化を完全に理解したという段階ではないのですが、それでも以前私が働いていたSI業界の文化とアジャイルな考え方が尊重されるグローバル企業とでは、やはり大きな違いがあるなということは、実際にはっきりと感じられますね。
まず、第一に大きく違うと思ったのは、会社の売上や利益に直接つながる、ビジネスの中心に近いところに開発チームが置かれていて、当然プログラマーはプロダクトオーナーなどビジネス担当の人と密接にやり取りをしながら開発を進めるというところがありますね。ビジネス担当の人とプログラマーが同じ部屋で作業をするということはもちろん、たとえば「この項目を外すとプログラムはすごくシンプルになるし、顧客にとっても画面がすっきりしてメリットがあると思いますが。」といったような提案をプログラマーからすると、あっさり認められて翌月のリリースに変更を反映するといったことが日常に行われています。少しでも使いやすいシステムの開発に貢献することで、売上に貢献するのだというモチベーションも湧きます。ウォーターフォールが中心のSI業界のやり方だと、項目の追加はまだしも削除などと言うことを提案しても、稟議書などを上げて何階層にもわたった承認が必要で、何週間、何か月も待つといったことは普通だと思います。そのような状況があるので、PGの側でもよいアイデアがあっても、わざわざ提案しようという気にはならないし、逆に、仕様書に書かれていることのみを実装して、余程の問題がない限りそれ以上のことはやらないという傾向が強くなってしまうところがあると思います。
それから、チームのサイズが小さくて、業務担当の人とプログラマーが直接会話できる距離にあるため、作成する文書は非常に少ないというところがあります。これはもちろんチームによると思いますが、開発後に説明のためWikiに情報を書くということはあっても実装前にWordやExcelの文書を作成するということはめったにないですし、作業時間の大半はEmacsVimEclipseといったツールを立ち上げてのコーディング、単体テストの作業が中心となります。以前は自分自身がコードを書くといった作業にあてられる時間は、全体のプロジェクトの中ではせいぜい10%程度でしたので、そこは大きな違いだと感じています。逆に言うと、自分の英語力のなさから、口頭で英語で説明を受けても理解しにくいというところがあり、時としてきちんと書かれた仕様書が恋しくなる時もあるわけですが、そこは文化の違いですね。
さらに、B2Cでどんどん新しい機能をリリースしていくという環境では、システム全体を何年もかけて作り直すという機会はほとんどありません。むしろ、細かい機能改善やバグフィックスを行うというプレッシャーが常にあり、その中で空き時間を見つけてリファクタリングを繰り返すという方向になります。そういう意味では、SIerのように新システムの開発をゼロから行うという機会はめったにありません。だから、常に最新の言語やフレームワークでなくては嫌な人には向いていないかもしれません。一方、SIerの場合は自分のシステムを維持管理するという機会は少ないのですから、むしろ、最新の最良の開発手法を取り込めばすごく面白い仕事ができるのに、実際には古いフレームワークを使い続けているケースが多いというのは残念なことですね。
なお、気にしていた自分の年齢ですが、やはり、グローバルな会社では35歳定年などということは全くないですね。今の会社の場合は全くの新卒というよりも、ある程度経験を積んだ人を中心に採用しているようなので、プログラマーとして自分くらいの年齢でも結構普通みたいです。実際、おじさんというレベルを超えて、そろそろ孫がいても不思議でない、おじいさんという感じの年齢の現役プログラマーもたくさん活躍しています。もちろん、年齢というよりはスキルによってポジションが決まるので、年齢が下の人がより上級のプログラマーということも普通にあり得ます。(おじさんと書きましたが、もちろん、グローバルには女性のプログラマーもたくさんいます。)

すでに定年を過ぎていますが、Amazonで引き続き達人プログラマーを目指すことになりました。

このたび9月末日をもってオージス総研を退職し、10月よりアマゾンジャパン株式会社に入社しました。今後はSoftware Development Engineerとして、日本をはじめ世界各国のAmazonのモバイルWebアプリケーションの開発を担当することになる予定です。
およそ7年間にわたり、前職のオージス総研ではソフトウェアアーキテクトとして、SOAやEAといった全社的なシステムのアーキテクチャから、上流のモデリングJava EEを使ったアプリケーションの開発など、技術者として様々な経験を積ませていただきました。私自身はこのブログでも何度も取り上げてきたように、モデリングオブジェクト指向といった技術を用いて、実際の基幹業務システムの設計などに活用することで、高品質で保守性の高いシステムの構築に貢献したいという思いがありました。そのようなシステムを構築、維持するためには高品質なアーキテクチャの構築が必要不可欠であり、それが、結果としてお客様の業務を効率化させ、さらにビジネスの価値を向上させることにつながるという信念がありました。
中でも私としては大変運の良いことに、実際のアプリケーション開発の現場に入って、Java EE、Spring、Hibernateといった標準技術やOSSを利用し、実際に再利用可能なフレームワークを段階的に構築し、複数のプロジェクトにわたって適用するという経験もできました。フレームワークチームとアプリケーションチームが完全に分断された世界で仕事をするのではなく、限られたリソースのなかでアプリケーションの要件をもとにフレームワークを段階的に進化させることが必要でした。複雑な金融商品ドメインモデルを構築したり、大量のトランザクションを処理するための高速化の仕組みを考えたり、ビルド自動化の工夫をするということは、単に新しい技術を適用するということ以上にわくわくする体験でした。
また、以前に自分は恵まれた環境で仕事をさせてもらっていることに感謝しなくてはいけないと思う - 達人プログラマーを目指してでも書いたように、SIerの職場環境としては珍しく、技術について熱く語ることのできる仲間が周りにたくさんいるチームで、大変に恵まれた居心地のよい環境で仕事をさせていただくことができました。一緒に仕事をさせていただいた上司や同僚には本当に感謝の気持ちでいっぱいです。
そういう意味で、なかなか自分から積極的に転職を考えようという気持ちにはなれなかったのですが、やはり、既に37歳という自分の年齢のためか、一般にこの業界で35歳定年説と言われているように、最近は開発現場でバリバリコードを書くという仕事からはどうしても遠ざかってしまっているところがありました。もちろん、自分の体力の衰えということもありますが、私としてはまだまだ現役でプログラムを書いていきたいという気持ちがありました。新技術の吸収力や理解の速さといった面では若い人にはかなわないかもしれませんが、リファクタリングモデリングの技術などは経験によって深まるものであると思うからです。
しかし、実際には年齢による能力の低下以上に、プログラミング作業の単価が業界の慣習から低く設定されているという事実があります。そのため、どうしてもアーキテクトや技術コンサルティングといった仕事をやらないと会社としては採算が合いません。技術の重要性に対する上司や同僚の理解があったにも関わらず、伝統的な人月に基づく受託開発を中心としたビジネスモデルで仕事をするSIerとしてはやむを得ないところであると思います。
そういう状況の中で、このブログのタイトルでもある「達人プログラマーを目指す」という自分の目標からどんどん遠ざかってしまっているのではないかという焦りや不安が常にありました。アーキテクトとしてパワーポイントやワードの説明資料を作成するのも広い意味でプログラミングの一種だと言って自分をごまかすこともできなくはないと思いますが、やはり、毎日IDEやエディタを起動してプログラミングスキルの向上や開発環境の改善に励みたいという思いがありました。
今回Amazonで応募したのはモバイルのWebアプリケーションを開発するソフトウェアディベロッパーとしてのポジションです。以下の記事の最後の部分で紹介されている、メイジャー・レイナー氏のチームに参加することになりました。
http://rikunabi-next.yahoo.co.jp/tech/docs/ct_s03600.jsp?p=001814&__r=1
Amazonはサービス企業のイメージがあるかもしれませんが、IT技術によって小売をサポートするという広い意味においてSI業界におけるユーザー系企業に近い立場であり、エンタープライズ開発の一種であると考えることもできると思います。今回AWSではなく、Amazon.comの本業である小売業を支えるアプリケーションの開発を行うポジションに応募したのは、エンタープライズアプリケーション開発者としての経験を少しでもいかしたいという自分のこだわりというところもありました。
Twitterでもちょうど日本人エンジニアを募集しているという話がありましたが(http://blog.jp.twitter.com/2011/09/10twitter.html)、最近は海外のIT企業が日本のマーケットに進出してきたということもあり、日本人プログラマーにも今後グローバルな環境で仕事をするチャンスが出てきたようですね。
ただし、日本で働くといっても、実際にほとんどの同僚が英語を話す外国人であり、日本の市場だけでなく、世界中をターゲットにした開発を行っています。詳しいことは書けませんが、面接はいわゆるシリコンバレー方式で、合計5時間くらいにわたって、同僚や上級のプログラマーからアルゴリズムやデータ構造など技術的な質問を英語で受け、心身ともにヘトヘトになりました。私の英語力の問題もありましたし、情報系の卒業でもなく、基礎的な計算機科学の勉強も不十分だったため、いきなりアルゴリズムに関するコードを書き下す問題にはなかなかてこずりました。
落ちても失うものは何もない、ダメでもともとという気持ちで応募したポジションですし、自分としてはこのチャンスを最大限に生かすべく、一日も早くAmazonのビジネスに技術力で貢献できる達人プログラマーの一員になることを目指して精いっぱい頑張っていきたいと考えています。
なお、ブログの方は今後もできる限り継続していきたいと思いますので、どうか引き続きよろしくお願いいたします。
n-14

普通の構造化プログラマーがオブジェクト指向の存在意義を理解するコツ

オブジェクト指向言語の存在意義を理解するのは難しい?

id:amapetasさんによる、ちょっと興味深い記事がありました。
オブジェクト指向言語が流行した必然性について考える(1) - Programmer’s Log
そして、その記事の中で説明されているのですが、やはり、C言語など構造化言語のプログラマーにとってはオブジェクト指向の存在意義を理解するのがなかなか難しいところがあるようですね。

初心者向けの書籍を最近読んでいないので、最近の書籍ではうまく説明されているのかもしれませんが、そんな話を聞いたことがないので、たぶん今でもオブジェクト指向に関する説明の始まり方は

「世界は全部オブジェクトで出来ているんじゃぁぁーーー」

という「オブジェクト至高教への洗脳」から始まっているものと推察しますw テンション高めの説明から入るのでドン引きする人多数な感じがかなりアレですね。オブジェクト指向の説明は独特な説明から入るので宗教っぽいんですよね、若干。宗教という表現をさけるなら思想、哲学といえば柔らかいでしょうか。

僕がその手の初心者向け書籍を読んだ時に思った事は「なぜオブジェクト指向言語(Java)で書く必要があるのか? 構造化言語(C言語等)ではダメなのか? 何が違い、何がメリットなのか?」にうまく答えられていない、という疑問でした。オブジェクト指向の世界観の説明で手一杯でそこらへんをうまく説明できていない気がしました。

構造化言語(C言語等)ではできなくて、オブジェクト指向言語(JavaC++等)で出来るようになったものとは何か?

引用元の記事ではオブジェクト指向自然言語の構造と関連させて論じているのですが、ここでは論点を変えて普通の構造化言語のプログラマーオブジェクト指向のメリットを理解してもらうためにはどのように説明したらよいかという点について考えてみたいと思います。

伝統的なプログラマーの頭の中にある数のイメージ

我々は小さい頃から、まず、ものを数えるということから自然数として数の概念を習得します。そして、成長するにしたがって、金額やテストの点数など、他のところで使われる数も存在することを体験を通して徐々に学んでいきますが、日常生活では基本的には整数は数えたり、大小比較のために使うものという考え方が根強く存在するでしょう。
もちろん、このような普通の整数の概念は(範囲に注意すれば)プログラムを使って表現することができます。しかしながら、コンピューターの内部で表現される整数が特定の個数のビット(あるいはバイト列)からなるデータに過ぎないという発想は本来一般人にはない考え方であると思います。
実際、コンピューターの整数データは32ビットや64ビットなど表現可能な値の範囲という厄介な性質がある一方で、画像を構成する一個一個の画素(ピクセル)の明るさや色、音声データ、通信データなど様々なところで利用されています。ベテランのプログラマーの頭の中にある整数のイメージは、一般人のそれとは違っているのかもしれません。ビットやバイトなどを意識する必要のある(意識できる)比較的低水準な言語を利用することで、プログラマーはコンピューターの構造と近いレベルで考える必要がある反面、効率的なプログラムを記述できます。
ここで重要なのは、コンピューターの構造上の都合で決まっている32ビットや64ビットの情報を使って表現できる値を使う必要があるということであって、これは伝統的なプログラマーの頭では自然な単位なのかもしれませんが、一般人の頭ではまったく自然な単位ではないということです。しかし、コンピューターの処理能力の急激な進歩に従って、最近のアプリケーションはどんどん高度な機能を求められるようになってきています。たとえば、銀行のシステムの金額計算であれば、32ビットの範囲を超えたなどという理由で計算結果が不正になることなどはあってはいけません。

オブジェクトはデータを抽象化したもの

Javaなどのオブジェクト指向言語では、クラスを使ってデータ型を抽象化することで、文字列、誤差なく計算できる金額、日付、リストなどアプリケーションの記述に便利な値(=オブジェクト)を生成して利用できるようになります。実際、Javaでは文字列は基本型に準ずる形で簡単に扱うことができるようになっていますが、単純な文字列結合のような処理であっても、本来のVM上の動作から考えるとかなり複雑な処理が必要なのですが、そういった処理は抽象化されているので普通は考える必要がありません。
コンピューター内部の構造によらない抽象化されたデータ型を利用したり、独自にクラスとして定義したりできることは、このようなオブジェクト指向言語のメリットの一つと考えられます。コンピューター(VM)の作りの制約に縛られた基本型の値を使う代わりに、適切に抽象化されたオブジェクトを使うことで、ビットやバイトといった発想を忘れてよりアプリケーションの要求に近い塊の単位で簡単にロジックを組むことができるようになるのです。
そして、オブジェクトに対して呼び出し可能なメソッドは、intなどの基本データ型に対する+などの演算に近いものであると考えることができます。Javaでは残念ながら独自の演算子を定義することはできませんが、実際にC++などの多くの言語ではクラスに対して演算子を定義することができます。
さらに、基本型の演算に対しても一種のポリモーフィズムは存在しています。*1実際、Javaのint型とfloat型では同じ32ビットでもまったく異なる内部表現を使っているのですが、同じ+演算子を使って足し算を実行することができます。しかし、両者はオーバーフローの有無など、かなり異なる振る舞いをします。

オブジェクト指向の入門書が理解を妨げる?

本来はSmalltalkRubyのように「すべてがオブジェクト」という純粋なオブジェクト指向の世界で考えた方が分かりやすいのですが、普通の構造化言語のプログラマーが最初にオブジェクト指向を学習するには、「社長と社員との関連」「哺乳類も犬もすべてオブジェクト」などということを考えるよりも、intなどの基本型や構造体の値に対する自然な拡張として、段階的にオブジェクトを考える方がしっくりくるのではないでしょうか?私自身も最初にオブジェクト指向を学習した際にはそのようなプロセスで徐々に理解しました。
多くのオブジェクト指向の入門書は、伝統的なプログラミングの考え方とはかけ離れた世界でオブジェクト指向を語ろうとする傾向があるので、かえって構造化プログラミングの知識があると理解を妨げるところがあるかもしれません。つまり、これらの入門書では、ちょっと便利なデータ型を定義できるという段階をスキップして、いきなり実世界の「もの」の関係をモデル化するところから説明しようとするために、かえってプログラミングとの関連性が見えにくくなっているところはあると思います。
つまり、Objectを普通の英語の意味で実世界の「もの」と考えるのではなく、コンピューターのメモリ上に確保された値のことを指す専門用語としてとらえた方が、構造化言語のプログラマーにとってはしっくりくるのではないでしょうか。たまたま、顧客など実世界のエンティティに対応したオブジェクトも必要かもしれませんが、プログラムの都合上で必要な値の塊も立派なオブジェクトになり得ます。

プログラミングでオブジェクト指向を習得するステップ

ところで、C++、Objective C、Object PascalJavaといった言語では、比較的低水準な伝統的なプログラマー脳が必要な基本型と演算子を使ってコーディングを行うことも、クラスライブラリーを利用して高水準のオブジェクト指向プログラミングを行うことも可能です。複数のパラダイムが混在しているため、なかなかい理解しにくいというところもあるかもしれません。
まずは、配列、文字列、日付といった抽象データ型がオブジェクトの一種なのであるというところから慣れ、次に、

あたりを順番に理解していくようにすれば、理解しやすいのではないかと思います。そして、プログラミングで正しく独自のクラスの作成ができるようになってくれば、自然に業務ドメインなど実世界の問題も、クラスを使ってモデリングする力がついてくるはずです。

*1:Javaを含めて、ここで説明する数値演算に対するポリモーフィズムコンパイル時に決定されるので実際にはオーバーロードされたメソッドの呼び分けに近いものですが。

*2:簡単なスタックやリストなどを自作してみるのも学習のためにはよいですね。

Pulseを使ってEclipseの設定を共有すると便利(ただし、閉鎖環境では使えません)

Eclipseワークスペース設定を共有することは難しい

EclipseJavaの開発では最も人気の高いIDEであり、もちろん、私も仕事でも自宅でもずっとメインのIDEとして使ってきました。もちろん、NetBeansやIDEAなど他の優秀なIDEもフリーで利用できる時代なのですが、やはり、入力支援機構やリファクタリング機能の豊富さについては、やはり、Eclipseが他と比べて一歩優れているように思われます。*1
そして、Eclipseの最大の特徴の一つは柔軟なプラグインアーキテクチャであり、豊富なプラグインの中から選択して好みの機能を拡張することができます。ただし、これはEclipseの最大のメリットでもあるのですが、大量のプラグインを管理して複数の端末で効率的に共有するということは案外大変なことでした。
Pleiadesのオールインワンパッケージを利用したり、また、SpringやJBossなど特定のフレームワークを対象にする場合は、Spring Tool SuiteJBoss Toolsなどを利用することで、有用なプラグインをまとめてインストールできます。これである程度問題は軽減されるとはいえ、結局

  • 足りない機能に対して独自にプラグインを追加
  • 起動パラメーターやフォーマットなどワークスペースレベルの設定をカスタマイズ
  • Java用、PHP用、Ruby用など複数の言語環境を使い分ける

などを行った場合、これらのカスタマイズした環境を複数のPC上で共有し、きちんとバージョンアップにも対応するような運用することはかなり面倒です。つまり、プロジェクトごとの設定情報はSVNなどの構成管理ツールを使って簡単に共有できるのですが、プロジェクトをまたがったワークペースレベルの設定を共有することが、簡単そうでいて実は難しいということがありました。
このような問題の一つの解決策はDropboxなどの共有サービスを使って、Eclipseの構成情報を共有することですが、それでもカスタマイズした複数の環境を管理することは容易ではありません。

Pulseを使ってどこからでもEclipseの設定を共有する

そのような問題を解決する手段として、Pulseというツールを利用すると非常に便利です。実は、私はかなり最近になって知ったのですが、実は、数年前から存在するようですね。MyEclipseという有償のEclipseのオールインパッケージを作っている会社が提供しています。
Pulseは個人で利用するだけであれば、以下からCommunity Editionを無償でダウンロードして使うことができます。
IDE Management by Secure Delivery Center - Genuitec
使い方はものすごく簡単です。まず、WindowsMacLinux用のバイナリが提供されているので自分のプラットフォームに合ったインストーラーを使ってインストールします。次に、以下のサイトであらかじめユーザー登録をしておくか、
IDE Management by Secure Delivery Center - Genuitec 
あるいは、Pulseの初期起動画面でRegisterを選択しユーザー登録を行います。

ユーザー登録時に使用したメールアドレス宛てに確認のメールが届くので、リンクをクリックして登録確認を行います。ユーザー登録が正しくできていれば、ログイン画面でログインすることで、以下のPulse Explorerの画面が開きます。

最初にPulse Explorerを起動した段階では、あらかじめ一覧から選択可能なEclipseの構成が表示されるだけですが、My Profilesのペインに好みの構成をドラッグすることで、独自のプロファイルを好きなだけ追加することができます。追加したプロファイルに対しては、以下の画面で好みのプラグインを追加することができます。

もちろん、新規のUpdateサイトを登録することで、予め登録されていないUpdateサイトのプラグインを追加することもできます。
そして、Install Nowのボタンをクリックすることで、実際にローカルにEclipseがダウンロードされてインストールされます。さらに、便利なことに、インストール後にプラグインの構成だけでなく、エディタのフォーマットなどワークスペースの設定情報をあわせて管理することができます。そのためには、以下のようにCollaborationタブをクリックし、Let Me At ItボタンをクリックしてTeam of One機能を有効化します。

Pulseは複数のプラットフォームに対応していますし、自分の使う複数のPC上にインストールしておけば、クラウド上に設定情報を共有することでどこでも同一の環境を利用することができるようになります。

有償版を使うとチーム間での共有も可能

さらに、月6$、年間60$を支払ってTeam Editionを購入することで、チームメンバー間でカスタマイズした設定を共有することも可能です。ちょっと高いと感じられるかもしれませんが、メンバー間で同一の環境を共有して同期させる手間を考えれば、むしろリーズナブルな価格設定と言えるかもしれません。
確かに、Eclipseの環境構築は面倒なのですが、このようなところに目を付けてビジネスにしてしまう発想には感心させられます。他には、EclipseSourceというEclipseを専門でビジネスをしている会社もあるようですが、オープンソースがビジネスになってしまう外国はちょっとすごいと思います。
それから、当然ですがこのような便利なツールも、インターネット接続が遮断されたいわゆる閉鎖環境では使うことができません。*2実際、閉鎖環境では外部からの情報が遮断されていることもあり、いまだにEclipse3.3などの太古の化石のようなバージョンが現役で使われているプロジェクトも存在するようです。セキュリティ面からやむを得ないところはあるとはいえ、そのような環境ではどんどん時代の最先端から取り残されていくというのは否定できませんね。

*1:個人的な慣れの問題が大きいことも確かなのですが。

*2:ただし、Private Labelと呼ばれるエンタープライズ向けのソリューションも提供されており、そのバージョンであれば閉鎖環境でも運用できるようです。Eclipseに限らず、アプリケーションを配信するメカニズムとして利用できるようですね。