はてなキーワード: ステートとは
NULL ならではの演算が含まれる振る舞い((NULL = NULL)はNULL、(FALSE=FALSE)はTRUE など)の特性をもつ場合にこそ、bool? を使いたいですね。
わたしの「スリーステート」という言葉の発想が、デジタルIC の端子 HIGH(1),LOW(0),HIGH-Z(電気的切り離し)から来ていたから、そこをしっかり説明しておくべきだった。「スリーステート」の言葉を直訳すれば3状態だけど、いくら3つの状態をもつからとて、なんでもbool?にはしないっすよ。大抵は私も列挙型を使いますね。しかしながら、値的に宙ぶらりんで集合演算にも参加しないような(しかし存在はしている)値をNULLと解釈できる人が使えば、bool?やint?はとても有用かと(DBやEXCELの空セルとも直交性がある)。そのあたりの意味がピンとこないようなら、手をださないほうがいいです。
という話でNullableの是非じゃない。
どれがいいかは、どうなんだろうな?
ただ、トライステートの考え方自体は間違っていないがNullableという命名方法は誤りだろ。NULLの意味が他の言語と違いすぎる。
正しくはUndefinedableだろ。 NULLとUndefinedは別物だ。
現実問題 中身を実装するとこういうことだよねぇ。
class { bool nullable, bool value, bool operator == (NULL){ if(nullable){ return true; } return false; } bool operator == (bool){ if(nullable){ throw; } if(value){ true; } return false; }
というオーバーヘッドとフットプリントを許容してまでクラス化するようなものなんだろうか?
便利そうだけど すっげぇ 気になる。
C#だからいいような気もするが、 bool演算一つのために 関数コールして ifステートを複数回判定するのはオーバーヘッドが大きすぎる気がする。
もしあなたがスリーステートの感覚を知らぬ、はいといいえしか概念を持たない人物なら、そもそも使わないほうがいいよ(RDB を触ったことないひと?)。一緒に仕事してて同僚に無理して使ってくれと頼まれたわけでもないんでしょ?3-stateの真似事をしたいなら、せいぜい System.Windows.Forms.CheckState でも使いまわしたら?ってことね。
近年、関数型プログラミングの重要性はいろんなところで叫ばれています。
Javaの最新バージョンに関数型プログラミングに関する新機能が加わりました。
Rubyも昨今、関数型プログラミングへのサポートが手厚くなってきています。
プログラミングの教科書の大手、オライリー社から、Javascriptで関数型プログラミングを行うための解説書が発行されました。
関数型プログラミングへの注目度は高まってきています。
おそらく、みなさんは既にオブジェクト指向が何か、を知っています。
でも関数型プログラミングとは何か、胸を張って語れる人は、周りに見当たらないかと思います。
実際、オブジェクト指向によってプログラミングする方法は、わかりやすい解説があちこちにある一方で、
関数型プログラミングとは何か、何が良いのか、ということについての、よいまとめは見つけることはできませんでした。
この記事を読む方の中で、「関数型プログラミングを取り入れるか・取り入れないか」で切実に悩んでいる人は、おそらくいないでしょう。
この記事はあまり細かいところに立ち入りません。関数型プログラミングを使う側の立場に立って、利点や向き・不向き、それが導くスタイルを書きました。
みなさんは鳥のように飛んで、高い空から、関数型プログラミングとは何か、何が良いのか、を見渡してください。
オブジェクト指向的アプローチは、名前をつけてプログラムを整理する。
関数型プログラミング的アプローチは、汎用部品でなんとかする。
Googleが近年リリースした言語、Goには、”継承”を直接サポートする仕組みが無いことが話題になりました。
また、Mac OSXの基幹ライブラリCore Foundationは、ライブラリ自体はC言語で書かれているにもかかわらず、その設計方針は明確にオブジェクト指向です。
その本質とは"名前をつけて対象を識別し、それを扱うこと"、にあります。
最もプリミティブなオブジェクト指向の対象は、ファイルハンドラです。あるファイルを開いて、読み込んで、あるいは書き込んで、ファイルを閉じる。
これらの処理をまとめたら、わかりやすいですよね?
対象に関する処理を、対象の周りにまとめる。これがオブジェクト指向の基礎的な理念です。
識別することとイコールで比較できることは、とても良く似ています。
イコールによる比較は、オブジェクト指向では鬼門であることが知られています。
PointクラスのインスタンスとColoredPointクラスのイコール演算をどう決めればいいかに、正解はありません(詳しくは"effective java"をご参照ください)。
また名前をつけて識別する対象は、フワフワしていてはいけません。
たとえば、"軍人の階級"をオブジェクトにしたとしましょう。"大佐"クラスのある兵士は名前のフィールドや、性別のフィールドを持っているでしょう。
ところで彼が昇格したときに何が起こるでしょうか。
新たに"少将"クラスのインスタンスが作られます。"大佐"クラスを破棄する前に、名前、性別、その他沢山のデータを引き継がなくてはいけません。フィールドを増やしたい場合はその都度コードに修正を加える必要があります(*)。
なるべくイコール比較を避けたい。対象は不安定なものではいけない。では何に名前をつけて、識別するか。そこにオブジェクト指向技術者の熟練度が現れるのです。
一方、関数型プログラミングでは、特定の何かに名前をつけるより、極力、汎用部品でなんとかしようとします。
関数自体をリストなどのデータ構造に詰めることもよく行われます。
実は、関数型プログラミングというのは本質を表していません。
関数をはじめとして、リスト・ツリーのようなコンテナ、手続きを抽象化したもの、回路を抽象化したもの。
あらゆる対象を値として、合成し、ときに分解し、新しい値を作ります。
変数に適用する処理を作りあげることが、とても簡単だからです。
四則演算が定義されたデータを詰めたデータ構造もまた、四則演算可能だったり。
誤解を恐れずに言うと、オブジェクト指向がトップダウンなのに対し、関数型プログラミングはボトムアップです。
関数型プログラミングをサポートする言語には、沢山の汎用部品が定義されています。
このような構造をインターフェイスとして、様々なライブラリが組まれているので、
たとえばモナドを知っていれば、30分程度でパーサー(解析機)を理解することができて、
パーサーを理解できれば、JSONパーサー・ XMLパーサー・markdownパーサー・C++パーサー ... などを理解するのはとても容易です。
理解しやすいこと。これが関数型プログラミングの大きな利点です。
追記:
また、汎用部品と型のお陰で、ライブラリのドキュメントが圧倒的にひきやすい、というメリットも有ります。
Haskellな人がPythonにトライした結果 - Togetterまとめ
関数型プログラミングは「厳密な事前設計を必要とするため、簡単なことをやるのにも時間が掛かる」。
>> map (*2) [1,2,3] [2,4,6]
邪魔な”儀式”や、"おまじない"のコードが徹底的に撤廃されているためです。
関数型プログラミングのコードは、潔癖かつ濃密です。
たとえばC言語でint hoge(int x,int y)が定義されているとき、hoge(3)はなんの意味も持ちませんが(コンパイルでコケますが)、関数型プログラミングでは意味があり、実際に有用です。
上の例では、「掛け算をする」(*)関数は、二引数関数ですが、それに引数を渡して作られた「2を掛ける」関数(*2)は、一引数関数になります。
関数型プログラミングでは、「簡単なことは簡単にでき、複雑なことは複雑にできる。ただし、間違ったことは殆どできないか、全くできない」。
また、静的型付けの力によって、コード補完は非常に強力になっています。インテリセンスの比ではないです。
たとえば、関数中のある表記の型を任意に表示できます(GHC/TypedHoles - HaskellWiki)。
やがてやってくる未来には、プログラムをテキストエディタで書くことは時代遅れになっているでしょう。
統合環境のサポートで、バグやミスの少ない、スムーズなプログラミングができます。
そしてその環境で動くプログラミング言語は、関数型プログラミングをサポートした言語なのです。
以下の様な兆候を感じたら、あなたはそのプログラムを関数型プログラミングで書くべきです。
一般に、オブジェクト同士の相互作用が複雑になるほど、オブジェクト指向では手に負えなくなっていきます。
そういうときは、オブジェクトを直接扱わず、替わりにその"相互作用"を扱うことで、複雑さを軽減するアプローチが有効です。
それこそが関数型プログラミング的アプローチです。
特にオブジェクト指向が有効なのは、プログラミング初心者がそのコードをいじるかもしれないときです。
関数型プログラミングは、強固さと柔軟さの代償として、高い学習コストを伴います。
オブジェクト間の相互作用が複雑でなく、着目している(名前をつけている)概念が安定しているとき。
そして、プログラムをいじる人たちの間で共通理解が図れているならば、オブジェクト指向が有利です。
遅延評価という機能によって、レガシーな言語で扱えなかった、巨大な数を扱うことができます。
関数型プログラミングで書かれたプログラムは、正確さが要求される、金融関連の業界で使われています。
手続きとしてパーサーを記述できるので、テキスト処理プログラムはより理解しやすく、メンテナンスしやすいものになります。
関数型プログラミングを知らない人は、「正規表現でおk」と言いますが、
彼の書いた複雑な正規表現は、半年後には(書いた本人でさえ)理解できなくなっていることでしょう。
手続き一般を扱うことができるので、途中で割り込みのある手続きの表現も容易です。
関数型プログラミングをサポートしていない言語ではコルーチン(ファイバー)などをつかってなんとかするしかありません。
さもなくば、非並行処理では普通に関数として記述できるところを、並行処理のために、Builder,Strategy,Command,Interpreterパターンを駆使して書き直すことになります。
Javascript使いの方は、Deferredなどの構造を使うでしょう(http://qiita.com/KDKTN/items/4c6986049d204f0645d8)。
C++使いの方はBoostで頑張りましょう。破滅的に解りにくいコンパイルエラーメッセージと格闘してください。
もう少し簡単な例をあげます。
あなたは、あるレシピにしたがって、自動的に料理を行うマシンの制御プログラムを書いているとしましょう。
1. まず玉ねぎを炒める。
2. 飴色になったら、肉を加えて炒める。
3. 野菜を加える。
4. 水を加えて煮る。
5. スパイスを加える。
…できませんよね?何故ならば、各ステップの"間に"、マシンのロボアームの位置や動きを調整する処理が必要だからです。
これをオブジェクト指向でやろうとすると、各ステップの副作用として、それらの処理を行うことになります。
そうすると、マシンが二機に増えた時などの変更量は、絶望的なものになります。
あるいは関数として表現するのを諦め、手順全体をDSLで記述できるようにします。
このアプローチは関数型プログラミング的です。しかし関数型プログラミングをサポートした言語の助けなしでは、そのDSLを記述するために沢山のユーティリティーコードを書かなくてはならないでしょう。
オブジェクト指向的アプローチでこの問題をエレガントに解こうとすると、クラス化の粒度を上げる事になります。
野菜クラス、フライパンクラス、ボイルクラス、フライクラス、焼き加減クラス、アームクラス、野菜の大きさクラス、切り方クラス、焼き方クラス、"焦げたよ"クラス、etc...
こうすると早晩レシピはプログラムのコード上から消え去ることになります。上記のたった5行は、依存性注入のオブジェクトグラフを構築するコードに取って代わることになります。そこには沢山の挙動の制御がオプションとして付記されているのです。
カレーなど、ある種のレシピに限定することで、見た目の理解しやすさを得ることができますが、一方それは表現力を損なうことを意味します。
C言語などではマクロを使うこともできますが、それは結局、関数型プログラミング的アプローチの意味するところと同じになります。すなわち、補助のために沢山のコードを書くことになるでしょう。
iOSのAppstoreアプリは、"無料"と書かれたボタンを押すと、それが"インストール"ボタンに変わり、それをもう一度押すと、ダウンロードの進捗を表すインジケータに変わり、それを押すとダウンロードをキャンセルできます。
このように、位置は同じなのに、ステートに依って見た目と機能が変わるボタンは複雑です。
これをオブジェクト指向で実現しようとすると、
という下らない問題にぶつかります。
一方関数型では、"機能"、"見た目"、"状態"、を独立に扱って、それらを合成してボタンを作るので、迷うことはありません。
「同じ位置にあるUIオブジェクトは、コード上で(インスタンスとして)独立して、他から干渉を受けない」
この条件が満たされているうちは、オブジェクト指向でGUIを実現することに無理はありません。
しかし、携帯端末のような小さい画面で、多くの機能を達成するためには、UI要素はコンテキスト依存的に複雑になりがちです。
近年、PCのディスプレイの大きさは、頭打ちになってきました。
画素数は増えているのですが、MacにおけるRetinaのように、複数ピクセルでひとつのドットを表すようになってきています。
これは、ひとつの画面に置かれるボタンなどのUI要素の数は、これから先の未来で増えることはない、ということを意味します。
したがって、未来のGUIのプログラミングは、注意深く機能をピックアップして制限するというデザイナーの努力を脇におけば、
関数型プログラミングの力を頼るしか無いでしょう。
つまり…
Haskell さいこうなのおおおおおおおおおおおおおおおおおお!! おしっこ漏れちゃうのおおおおおおおおおおおおおおおおおおおお(゜∀。)ワヒャヒャヒャヒャヒャヒャ
1. google:すごいHaskellたのしく学ぼう を注文する。
2. Download Haskell を自分のPCに導入する。
3. コンソールにghciと入力して、対話型コンソールを立ち上げる。
4. 次の関数をコンソールに打ち込んで、結果を見る。即値で書かれているところとかをいろいろ変更してみて、感動する。
take 4 $ map (*2) [1..]
追記:
いかがでしたか?
ちまたには、関数型プログラミングの利点は変数が無いことだ、とか、より安全だから、とか、より速いから、などという妄言が満ち溢れています。
オブジェクト指向と関数型プログラミングは、水と油ではありません。プログラマは自分のプログラムに最適なアプローチを選ぶことができます。
一般にはあまり知られていないことですが、Haskellにもオブジェクト指向へのサポートがあるんです(Lensライブラリ、これを使用したサードパーティ製ライブラリも最近増えてきています)。
この記事を読んだオブジェクト指向プログラマのあなたが、少しでも関数型プログラミングに(そしてHaskellに)興味を持ってくださって、ホームセンターの大人用オシメのコーナーが大賑わいになれば幸いです。。
http://b.hatena.ne.jp/entry/wp-d.org/2014/02/26/5709/
deployでGITの是非を語るならまだ分かるが
まるで、FTPに使いどころがあるような書き方をしてるのがいて
ブコメが恐怖に満ちてたので書く。
理由
まずなによりもこれ。FTP使うのは、公開共有フォルダと同じレベル。
・FTPなんて立てなくても、SSH/SCP/SFTPが確実にあいてる。
あえてFTPサーバー立ててる時点で相当怪しい。確実にアホな理由。ユーザーが使えないからとか
・FTPSは新規に使うモノじゃない。
FTPS意識するような人なら、既にSSH/SFTPなり使ってる。
FTPSはレガシーFTPに対して、応急処置でう使うモノであり、新規採用なんてありえない。
・FTPというステートフルなプロトコルは、プログラムには本来扱いにくい
なのにあえてFTP立ててる時点で相当怪しい。その辺から離れた世界の匂いしかしない。
FTPとHTTPのオーバーヘッドとか、このブロードバンド(死語)時代に何言ってるのよ?
というかね、転送効率がそこまでシビアだったら別な方法選択するからありえない。
あとさー。いまだにデカイファイルはFTPあけてファイル配るみたいなことやってるから
勘違いする馬鹿がいっぱいいると思うの、そろそろやめていいよ。誰も困らないから。
アホなユーザーにFTP利用させる==公開共有フォルダ化したどころかウィルスばら撒く温床にまでなった。
というかGumblarのせいでこの世からFTPは駆逐されたはずだが、
なんで時と場合を考えろみたいな話になってるの?
なんなの。なにこれすごくわい。
下見て思った。
http://mizchi.hatenablog.com/entry/2013/09/25/190313
知識が離散して蓄積されてない気がする。
シングルページスタイルのJavaScriptWebアプリケーションのアーキテクチャ
JavaScriptMVCライブラリを利用するよ!
とりあえず今回は、乱立する名称候補たちを紹介
HTML5って言いたいだけのJavaScrtipt使ったスマホのアプリフレームワークとかも呼ばれたり。
HTML5とか言われる前にJavaScriptアプリケーションやるとこれになってた。
アーキテクチャとしては、もっとも正解の名前なのだが、NET系界隈でしかきかん。
ASP.NET MVC Single Page Applicationは、キー要素がかなり詰まってて、参考になる。
このあたりのやろうとしてる奴は一度触っておくが吉
JavaScriptMVCライブラリ、AMD等の依存モジュール管理とか
英語ソースだと結構ポピュラーな感じの名前だが、指針的な匂いでアプリケーションとは言わない感も。
日本でも一時期、大規模Javascript開発とか言われてたが、Bakcbone.jsって名前に変わった。
Node.jsと被るために、このアーキテクチャの説明にはあんまり使われない。
動物本の、
「ステートフルJavaScript MVCアーキテクチャに基づくWebアプリケーションの状態管理 」
原題は、「JavaScript Web Applications」
これだけで、どのぐらい困ったか分かる感じ。
ちなみに、JavascriptMVCアーキテクチャの解説本としてはありなので読むが吉
といっても、10年ぐらい前からXHRとHTMLとDOMでほげるのは
実はあんまり変わってない。
Java界隈から出したかっただけ。oracleが呼んでた気がする。
Struts死んだけど、JSFでやるの?JSF無理筋だから違うフレームワーク作るの。
JSFみたいな抽象化使い始めると、コボルみたいにJava世界に閉じそうだけど大丈夫なの?
このあたりのライブラリ使えば、簡単にこのスタイルのアプリ作れると思ってるでしょ?
ライブラリの名称なのだが、背負ってるものは、大体この界隈全て
だけど、使えば、この界隈のアプリが簡単に作れるかというと、そうでもない。
プログラムはclassに記述します。たとえばSampleという名前のclassを作る場合、Sample.csファイル内に次のように書きます。(C#の場合、ファイル名とクラス名は同一でなくても良い。複数のクラスを書いても良い)
public class Sample { }
プログラムはclass内のMainメソッドの先頭から実行されます。Mainメソッドは次のように書きます。
public class Sample { public static void Main( String[] args ) { // 処理を書く } }
Console.WriteLine( "Hello world" );
コメントです。
// 一行コメント /* 複数行コメント */
// 変数 int num;
データ型です。C#のデータ型には値型と参照型とがあります。以下は値型のデータ型です。
// int(整数)型 int num; // char(文字)型 char c; // float(単精度浮動小数点)型 float val; // double(倍精度浮動小数点)型 double val; // bool(論理)型 bool flag; // DateTime(日付)型 DateTime date;
以下は参照型のデータ型です。
// String型 String s; // 配列型 String[] array;
プログラムをコンパイルするには、コマンドラインで以下のようにします。
csc Sample.cs
プログラムを実行するには、コマンドラインで以下のようにします。
Sample.exe
mono ./Sample.exe
int、float、double型の変数に数値を代入できます。int型には整数だけ代入できます。float、double型には整数でも小数でも代入できます。
int i = 2; int i = 100000000; float num = 1.234f; double num = 1.234;
四則演算です。
num = 1 + 1; num = 1 - 1; num = 1 * 2; num = 1 / 2;
商の求め方です。割る数と割られる数が両方とも整数の場合、計算結果の小数点以下が切り捨てられます。
num = 1 / 2; // 0
割る数と割られる数のどちらかが小数の場合、計算結果の小数点以下が切り捨てられません。
num = 1.0 / 2; // 0.5 num = 1 / 2.0; // 0.5 num = 1.0 / 2.0; // 0.5
余りの求め方です。
// 余り mod = 4 % 2
インクリメントとデクリメントです。
// インクリメント ++i; // デクリメント --i;
String str = "abc";
// 結合 String join = "aaa" + "bbb"; // 分割 String[] record = "aaa,bbb,ccc".Split( "," ); // 長さ int length = "abcdef".Length(); // 切り出し "abcd".Substring( 0, 2 ) // abc // 検索 int result = "abcd".IndexOf( "cd" ) // 見つかった場合はその位置、見つからなかった場合は-1が返る
配列です。
// 配列の宣言 int[] array;
配列の生成です。配列の生成時には要素数を指定するか、初期データを指定します。
int[] array; // 要素数を指定して配列を生成 array = new int[5]; // 初期データを指定して配列を生成 array = new int[] { 1, 2, 3 }; // 宣言と同時に配列を生成 int[] array2 = new int[5];
配列の要素の参照と代入です。
// 要素の参照 array[0] array[1] // 要素の代入 array[0] = 1; array[1] = 2;
array_num = array.Length;
int[] from = new int[] { 1, 2, 3 }; int[] to = new int[5]; from.CopyTo(to, 0);
if文です。
if ( 条件 ) { }
if ~ else文です。
if ( 条件 ) { } else { }
if ~ else if文です。
if ( 条件 ) { } else if ( 条件 ) { }
while文です。
int i = 0; while ( i < 5 ) { // 処理 ++i; }
for文です。
for ( int i = 0; i < 5; ++i ) { // 処理 }
int[] fields = new int[] { 1, 2, 3 }; foreach (int field in fields) { // 処理 }
C#では関数をメソッドと言います。メソッドを作るには次のようにします。戻り値を返却するにはreturn文を使います。
static int sum( int num1, int num2 ) { int total; total = num1 + num2; return total; }
ファイル入出力です。ファイル入出力を行うには、プログラムの先頭に以下を記述します。
using System.IO;
以下がファイル入力の雛形になります。ファイルのオープンや読み込みに失敗した場合、catch節に処理が移ります。
String filename = "text.txt"; StreamReader reader = null; try { reader = new StreamReader(filename); String line; while ((line = reader.ReadLine()) != null) { } } catch (IOException e) { // エラー処理: } finally { if (reader != null) { try { reader.Close(); } catch (IOException e) { } } }
またはC#ではusing ステートメントと言うものがあり、この様にも書ける
String filename = "text.txt"; using (StreamReader reader = new StreamReader(filename)) { try { String line; while ((line = reader.ReadLine()) != null) { // 読み込んだ行を処理 } } catch (IOException e) { // エラー処理: } }
usingをつかうとCloseがなくなったことからわかるようにusing(){}を抜けるときに自動的にDisposeメソッドを呼び出し、オブジェクトを廃棄する。その分コードがスッキリするが、使いにくい場面もあるので考えて使うこと。
以下がファイル出力の雛形になります。ファイルのオープンや書き込みに失敗した場合、catch節に処理が移ります。
String filename = "text.txt"; StreamWriter writer = null; try { writer = new StreamWriter(filename)); writer.WriteLine("abc"); writer.WriteLine("def"); writer.WriteLine("fgh"); } catch (IOException e) { // エラー処理: } finally { if (writer != null) { writer.Close(); } }
こちらもusingを使って書ける。が、割愛する。
C#でよく出てくる知っておいたほうがよい文法の一覧です。
繰り返し文の途中で抜けるにはbreak文を使用します。
for ( i = 0; i < 5; ++i ) { if ( 条件 ) { break; // 条件を満たす場合、for文を抜ける。 } }
残りの部分処理をスキップし、次の繰り返しに進むにはcontinue文を使用します。
for ( i = 0; i < 5; ++i ) { if ( 条件 ) { continue; // 条件を満たす場合、残りの部分処理をスキップし、次の繰り返しに進む。 } }
例外を投げるにはthrow文を使用します。
throw new Exception( "Error messsage" );
try { // 例外が発生する可能性のある処理 } catch ( Exception e ) { // 例外発生時の処理 }
Google エンジニアの Steve Yegge 氏、Google+ への懸念を漏らす
http://japan.internet.com/busnews/20111013/8.html
で記事になってたけど、原文とちょっと要旨が変わっちゃってサービスへの警鐘みたいになってしまってたので、全文訳してみた。くそ長い。お暇な方どうぞ。
(2011/10/19 08:14)ありがたい誤訳の指摘をいただいたので3カ所修正。
Stevey の Google プラットフォームぶっちゃけ話
僕は6年半ばかり Amazon にいて、今はそれと同じくらい Google にいる。この二つの会社について強く感じることは(しかもその印象は日々強まるのだけれど)、 Amazon は全てにおいて間違っていて、 Google は全てにおいて正しいということだ。そう、やりすぎな一般化だけど、驚くほど正確だと思う。いやもうとにかくね。百、いや二百のポイントで二つの会社を比較することが出来るだろうけど、僕が正しく覚えていれば、 Google はそのうち三つを除いて優れている。実にある一点に関してはスプレッドシートを書いたんだけど、法務が外に出すなって言うんだ。リクルーティングは惚れ込んだみたいだけどね。
つまり、まあ簡単に言えば、 Amazon の人事採用プロセスってのは基本的に欠陥品なんだ。だって、チームがチーム毎に、自分達のために人を採用するんだぜ。だから、色々平均化の努力はしてるみたいだけど、採用基準はチームによって信じられないくらいバラバラさ。そんでもって作業工程ってのも腐ってる。ソフトウェア信頼性工学なんてお呼びじゃないし、エンジニアに何でもやらせようとするんだ。コーディングする時間もないくらい。もちろんこれもチーム毎にバラバラで、要するに、運次第ってところ。施しやら困った人を助けるのやら、コミュニティに貢献するのやら、そんなのはもってのほか。バカにしに行くんでもなけりゃ、近寄るべきじゃないね。それにまた施設も染みだらけの壁に囲まれた箱みたいな家畜場で、装飾やらミーティングエリアなんてものには一銭も使ってない。給料やら福利厚生なんてのも最悪だ。まして最近じゃあ Google やら Facebook っていうライバルがいるのにね。社員特典なんてものも見たこと無かったな。採用通知の番号を照合して、ハイ終わり。コードベースも悲惨そのもの。エンジニアリング基準ってものがないんだから。チームによっては個別にがんばっていたくらいかな。
公平に言えば、彼らは良いバージョン管理ライブラリシステムを持っていた。これは僕らもまねるべきだし、僕らのところには同様のものが無い、良い pubsub システムもあった。でも多くの部分で彼らが使っていたのは、ステートマシンの情報を RDBMS に突っ込んだり読み出したりするだけのくそみたいなツールの塊だった。僕らならただでも欲しくないようなね。
僕が思うにその pubsub システムとライブラリ管理システムが、まさに Amazon が Google より優れている三つのうちの二つだ。
早期にリリースして、狂ったようにイテレートするってのも彼らのうまいところじゃないかって言うかもしれない。けど逆もまたしかり。彼らは早期にリリースすることを何にもまして優先する。品質保持やらエンジニアリング規則、その他長い目で見たら重要になってきそうなものはみんな後回し。そんなだからたとえ市場で競争相手よりアドバンテージがあったとしても、結局ちょっとしたことをやるのにも問題を起こしちゃうよね。
でも、一つ、そんな政治的な、思想的な、技術的なへまを補うだけの、彼らが本当に本当にうまくやってることがある。
Jeff Bezos は悪名高きマイクロマネージャーだ。彼は Amazon の小売りサイトの1ピクセルまで管理する。彼は以前 Larry Tesler を雇った。 Apple の主任科学者で、たぶん世界で最も有名で尊敬される HCI エキスパートさ。そんでもって、 Jeff は Larry が言ったことを、 Larry が辞めるまで3年間無視し続けた。 Larry は大規模なユーザビリティ研究もやっただろうし、少しの疑いの余地も無く誰もそのひどいサイトを理解できないってことをデモしたに違いない。けれど、 Jeff は1ピクセルたりとも動かさせはしなかった。トップページにぎっちりつまった内容の1ピクセルたりともね。それらはまるで何百万という彼の貴重な子供達なのさ。けれど Larry はそうじゃなかった。
マイクロマネジメントが Amazon が僕らよりうまくやっている三つ目ってわけじゃあない。つまり、まあ、彼らはうまくマイクロマネジメントをやっていたと思うけど、それを強みって言いたいわけじゃ無い。まずは何が起こっているかみんなに理解してもらうための文脈を準備しているだけさ。僕らはこれから、公衆の面前で、 Amazon で働きたけりゃ私に金を払えと言ってのける男について話すわけだからね。誰かが彼に反対したときは、彼は彼の名前入りの小さな黄色いポストイットを手渡して、誰が会社を動かしているかを常に忘れさせまいとする。思うに彼は全くの… Steve Jobs なのさ。ファッションとデザインセンス抜きのね。 Bezos はとんでもなく頭が切れる。誤解しないで欲しい。彼の前じゃ、普通のコントロールフリークなんてヤクが極まったヒッピーみたいなもんだよ。
それである日 Jeff Bezos が指令を出した。まあ彼がいつもやってることなんだけど。その度にみんなはピコピコハンマーで叩かれるありんこみたいに走り回るんだ。でもそのある一度、2002年かそのくらいのことだったと思うけれど、彼は指令を出した。とんでもなく巨大で、目の玉が飛び出るほど重たいやつを。普段の指令が頼んでも無いボーナスに思えるようなやつを。
彼の巨大な指令はこんな感じだった。
1)この時点より、全てのチームはサービスインターフェースを通じて全てのデータと機能を公開すること。
2)各チームは各々そのインターフェースを通じて通信しなければならない。
3)その他の全てのプロセス間通信は許可されない。ダイレクトリンク、他のチームのデータソースから直接データを読むこと、メモリ共有モデル、バックドア、全てを禁じる。ネットワーク越しのサービスインターフェースを経由した通信だけが許可される。
4)使用する技術は問わない。 HTTP 、 Corba 、 Pubsub 、 カスタムプロトコル、何でも良い。 Bezos は気にしない。
5)全てのサービスインターフェースは、例外なく、外部に公開可能なようにゼロから設計されなければならない。すなわち、チームは全世界のデベロッパに向けてインターフェースを公開することができるよう、設計し、計画しなければならない。例外は無い。
6)そうしない者は解雇される。
7)ありがとう!良い一日を!
ハハ!。ここにいる君たち150人ちょっとの元 Amazon 社員ならもちろんすぐにおわかりの通り、7番は僕が付け加えたジョーク。 Bezos は間違いなく君たちの一日なんかに興味ないからね。
それでも、6番は、本当だった。だからみんな一生懸命会社に行った。 Bezos は、さらに上級のチーフ熊ブルドッグであるところの Rick Dalzell に率いられた数人のチーフブルドッグを雇って、成果と進行を監視させた。 Rick は元レンジャーで、陸軍士官学校出身で、元ボクサーで、元 Wal(ごにょごにょ)Mart で拷問のような削減をやってのけた人物で、デカくて愛想の良い、「堅牢なインターフェース」という言葉を連呼する男だった。 Rick は歩き回り、「堅牢なインターフェース」について語り回り、そして言うまでも無く、みんなたくさんの進展をし、 Rick にそれを知らせた。
それからの数年間、 Amazon 内部はサービス指向アーキテクチャに姿を変えていった。その変化を形にしている間に、彼らは非常に多くのことを学んだ。 SOA に関する学問や論文は当時もいくつかあったけれど、 Amazon のとんでもない規模からすれば、そんなもの、インディ・ジョーンズに向かって「通りを渡るときは左右をよく見るんだよ」って言うくらいの意味しかない。 Amazon の開発スタッフはその途上でとにかくたくさんの発見をした。そのほんの一部をちょっぴり挙げると、こんな感じだった。
とまあこれらがほんの一例。他にもたくさんの、おそらく何百の、 Amazon が見つけた個別の発見や教訓があった。外部サービスにはおかしなところがいくつもあったけれど、君たちが考えるほどじゃあない。サービスに対して組織するってことは、外部のデベロッパを信用できないのと同じように、お互いを信用することなんてできないんだということを、チームに教えてくれたんだ。