Hatena::ブログ(Diary)

LEMON IN THE BOOKSTORE このページをアンテナに追加 RSSフィード

2011-04-30

アーキテクトとステークホルダ

アーキテクトの仕事とは何かというと、「ステークホルダの観点を集約し適切なデザインをする」こと。

これはinformation architectだろうが、application architectだろうが同じ事で、デザインの対象が情報設計なのかアプリケーションの設計なのかの違いだけ。

まあ、同一のシステムを対象としてればほとんど同じなんだろうけど。

で、ある事業がコンシューマ向けのWebアプリケーションをローンチしたとして、そのアプリケーションのアーキテクトは何をしなきゃいけないのかということをちょっと整理する。

まず、「第一にアークテクチャとは何の為にあるのかということ。」を明確にすること。

それはほとんどの場合「ステークホルダの利益のため」。

時々アーキテクトの趣味をそのままアーキテクチャに反映させるだけの新規技術オタクがいるけど、それはちょっといただけない。

で、このステークホルダの洗い出しとヒアリングを繰り返して適切なデザインを提案していくのがアーキテクトの仕事になる。

ヒアリングというのは、ある程度の裁量権をもって、方針を決定する事ができる側が行う事であるから「相談」や「お伺い」ではない。

弁護士に法廷戦略について、提案されることはあっても相談される事は無いのと同じで、それだけの信頼関係が要求される。

逆にアーキテクトは、このステークホルダのなかで業務領域をよく知る人に対して十分なリスペクトをもって信頼関係を築いている必要がある。

たとえば、ステークホルダには以下のような部門が考えられる。

  • 運用部門
  • 顧客サポート部門
  • 営業部門
  • 開発部門
  • 製品企画部門
  • PR/宣伝部門
  • 経理/法務部門
  • 情報セキュリティ部門

などなど。

それぞれのニーズや願望、展望などをヒアリングし設計を行うのだが、残念ながらそれらすべてかなえられる訳ではないし、要求していることが本当に達成したい事とも限らない。

ここで重要なのは、願望や展望から機能要求と非機能要求を見いだし、それをある程度明示的にアーキテクチャ要素に切り出していく事だ。

特に非機能要求は、明示的に要求されなかったり、横断的関心として浮かび上がってきたりする為、意識的/反復的にアーキテクチャ上の非機能要求を精査していく必要がある。

代表的な非機能要求には次のようなものがある:

  • セキュリティ
  • 可用性
  • 耐障害性/障害抑止性
  • 運用性
  • 保守性/解析性/変更性
  • 使用性
  • テスタビリティ
  • パフォーマンス
  • スケーラビリティ

などなど。

これらのことを一人で出来るのはまあ、理想的なのかもしれないが、こういった要求についても各分野のスペシャリストに委譲していくことも組織としては大事。

2011-04-23 本当のハイテク企業になるために このエントリーを含むブックマーク

以前、ポールグレアムが、「Yahooに起きてしまった事」として、テクノロジー企業としてスタートしたものが徐々にメディア企業としてハッカー文化が摩耗していくといった話をしていた。

Webテクノロジが本当にハイテクだったかはさておき、コミュニケーションのためのWebサービスを開発するという事は、単純なWebサイトを構築したりどこかから拾ってきたCMSをいじったりするのとは本質的に違う。

雑誌を編纂するようにエディトリアルに価値の本質があるわけではないし、コンテンツプロバイダーのようにクリエイティブそのものに価値の本質があるわけではない。

Webサービス企業にとっての本質的価値とはサービスしているソフトウェアドメイン/構造そのものだ。

サービスしているソフトウェアドメイン/構造そのものに本質的価値をおく企業は、その表面的なプレゼンテーション層に価値のメインストリームをおかない。

たとえばそれは、Googleにとってはsearchであって、Facebook/Twitterにとってはsocial graph と friend feedであったりする。

このアプリケーションソフトウェアドメイン/構造に本質的価値をおく企業をこれからのWebサービス企業の形だとすれば、プレゼンテーション層やプラットフォームというものは販促や小売、流通、営業であって、商品開発ではない。

それは決してプレゼンテーション層/プラットフォームに価値が無いことをいいたいのではない。戦略としてプレゼンテーション層に力を入れる事も消して間違いではない。

レイヤが違うという事を(エグゼクティブ、スタッフ、組織が)認識しているかどうかだ。Webサービス、WebアプリケーションとWebページの違いを本当にわかっているのかどうかだ。

それは、販売のフィードバックを商品開発部門がうけとることがあっても、販促部が直接商品開発をすることはないようなものだ。

こういった企業にとって、ソフトウェア開発計画とは事業計画/人事計画でもある。

事業計画/人事計画のようなというのは、開発行程とそのリソース配分そのものがビジネスの進捗に直結するからであるし、

インフラコストと人件費がコストの中心となる企業にとって、コスト改善の為の幾多の意思決定がソフトウェア開発には内在しているからだ。

技術的負債という言葉がある。

技術的負債(英: Technical debt)とは、
行き当たりばったりなソフトウェアアーキテクチャと、
余裕のないソフトウェア開発が引き起こす結果のことを指す
新しい比喩である。「設計上の負債(design debt)」とも言う

というものだ。ソフトウェア開発計画の方針が簡単にぶれてしまえば、事業計画の方針がぶれてしまったときにコストが発生するようにソフトウェア開発にとってもコストが発生してしまう。

製造業が、中国に工場を造るという事業計画を立てて進捗していたが、途中で国内工場の増産にシフトするといった場合、その変更コストは試算され、しかるべき意思決定者によってそのコストが受容される事になるが、ソフトウェア開発企業ではなかなかそうはいかない。

ソフトウェアの技術的負債は、定量化しづらく、コストの試算がきわめて難しい。それはソフトウェア開発工数/工期の見積もりが安定しないのと同じで、複雑系の中にあるものをブラックボックスとして評価する類いのものだからだ。

そして、ソフトウェアアーキテクチャとは、ソフトウェア開発計画に基づいて、適切な抽象化構造をソフトウェアに提供してくことなのだが、この抽象化構造を適切な意思決定者に不可視である場合、この負債の事前評価はさらに難しくなる。

ある意思決定を行った事が、つぎの意思決定への多大なコストを生みうるからだ。

ソフトウェア開発では、個人的な予知に基づいた設計はタブーとされる。不当に複雑な抽象を与えてしまう可能性があるからだ。予知ではなく、現在と計画において適切な構造を提供することが重要だ。

その構造のインクリメンタルな発展であれば、修正コストは最小限に保てる。その構造そのものを別モノに変換するのであればそれが中核的な抽象であればあるほど修正コストは肥大化する。

それは他の業界であれば、

いままで半導体工場を提供していた企業が、その工場でようかんを製造すると方針転換するといえば想像がつくコスト増なのだが、アーキテクト不在のソフトウェア企業であれば、このコストですら秘匿されたものとなってしまう。

これらの可視化と評価はきわめて難しいことだが、

ソフトウェア企業がさらに発展していく為の重要なファクターとなる。

WEB+DB PRESS Vol.62

本日発売のWEB+DB PRESSPerl Hackers Hubにて、技術的負債定量的評価とアーキテクチャパターンを簡単ながら扱っている。

ぐだぐだと書いたが結局のところただの宣伝なのだ。

2011-04-18 position:fixedのサポートを検査する このエントリーを含むブックマーク

android端末のwebkitや普通のブラウザはposition:fixedをサポートしているけどiOSwebkitは何故かサポートしていないので、うざい。うざいけど判別しなきゃ行けないのでsnippet

var isSupportedPositionFixed = (function (body){
    var element = document.createElement('div');

    element.innerHTML = 'x';
    element.style.position = 'fixed';
    element.style.top      = '0px';
    body.appendChild(element);

    var bodyScroll = body.scrollTop;
    body.scrollTop = 100;
    var elementTop = element.getBoundingClientRect().top;
    var isSupported = (elementTop === 0) ? true :false;
    body.removeChild(element);
    body.scrollTop = bodyScroll;

    return isSupported;

})(document.body);

console.log(isSupportedPositionFixed);

解説としては、fixedのエレメントを使って、少しbodyをscrollしてgetBoundingClientRectで実際の位置を取得して、動いていないかどうか確認するという感じ。

2011-01-04 memo: monad in javascript このエントリーを含むブックマーク



(function(){

//unit: a -> M[b]
var unit = function(value){
    return {
        value : function(){return value}
    };
};
//bind: M[a] -> (a->M[b]) -> M[b]
var bind = function(m,proc){
    return proc( m.value() );
};

// func a->M[b]
var x2 = function(x){return unit(x*x)};
var inc = function(x){return unit(x+1)};

//return a >>= f ≡ f a
print( bind( unit(10) , x2 ).value(), x2(10).value());
//m >>= return ≡ m
print( bind( unit(10) , unit ).value(),unit(10).value());

//(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
print(
    bind( bind( unit(10) , x2 ) ,inc ).value(),
    bind( unit(10) , function(x){ return bind( x2(x) ,inc)}).value()
);

})();

評価とか型とかないからあれだけど、

一番単純な形だとこんな雰囲気になるはず。

これだとなんの役にも立たないので、構造を覚えていて

valueが呼ばれるまで評価しないmonadを作ってみる。


(function(){

//unit: a -> M[b]
var unit = function(value){
    var ret = (value.call)  ? value : 
              (value.value) ? value.value : function(){return value}
    return {
        value : ret
    };
};
//bind: M[a] -> (a->M[b]) -> M[b]
var bind = function(m,proc){
    return unit(function(){ return proc( m.value() ).value() });
};
// bindが逐次実行じゃなくて評価前の状態を保存する
// ように作る。

// func a->M[b]
var x2 = function(x){return unit(x*x)};
var inc = function(x){return unit(x+1)};

print( unit(10).value());
print( unit(unit(10)).value())
print( bind(unit(10),x2).value());
print( bind( bind(unit(10),x2),inc).value());

//return a >>= f 竕。 f a
print( bind( unit(10) , x2 ).value(), x2(10).value());
//m >>= return 竕。 m
print( bind( unit(10) , unit ).value(),unit(10).value());

//(m >>= f) >>= g 竕。 m >>= (\x -> f x >>= g)
print(
    bind( bind( unit(10) , x2 ) ,inc ).value(),
    bind( unit(10) , function(x){ return bind( x2(x) ,inc)}).value()
);


var process = [inc,inc,x2,x2,inc];
var m = unit(1);
process.forEach(function(e){
    m = bind( m , e );
});
print("before evaluate");
print(m.value());
print("afater evaluate")

})();

Array.prototype.flatMapを実装するとArrayもmonadに。

Array.prototype.flatMap = function(f){
    var ret = [];
    this.forEach(function(e){
        ret = ret.concat( f(e) );
    });
    return ret;
};

//unit: a -> M[b]
var unit = function(value){
    return [value];
};
//bind: M[a] -> (a->M[b]) -> M[b]
var bind = function(m,proc){
    return m.flatMap(proc);
};

// func a->M[b]
var x2 = function(e){return unit(e*e)};
var inc = function(e){return unit(e+1)};

//return a >>= f == f a
print( bind( unit(10) , x2 ), x2(10));
print( [10].flatMap(x2),x2(10));
//m >>= return == m
print( bind( unit(10) , unit ),unit(10));
print( [10].flatMap(function(e){return [e]}), [10]);


//(m >>= f) >>= g == m >>= (\x -> f x >>= g)
print(
    bind( bind( unit(10,1) , x2 ) ,inc ),
    bind( unit(10,1) , function(x){ return bind( x2(x) ,inc)})
);

print(
    [10].flatMap(x2).flatMap(inc),
    [10].flatMap(function(x){ return x2(x).flatMap(inc)})
);

2010-12-13

世代間認知不協和

コミュニケーションを媒介するサービスにとって、そのコミュニケーションがどのように育まれているかという点について深い知見を得るというのはとても重要なことだ。コミュニケーションのスタイルというのは日々変化するもので、何が正しくて何が正しくないという知見は簡単に変化してしまう。この変化をとらえていくということは非常に難しい。

最近、Willcomが誰とでも定額、連続通話時間が10分以内の電話はすべて定額の範囲に収まるというプランを発表した。Willcom内通話の定額は以前からあって、2時間45分とかそのあたりで定額がいったん打ち切られるといったようなものだったと記憶している。

ソフトバンクウィルコムケータイの無料電話が流行るにつれて、一部の中学生たちが面白い使い方をしているという話を聞いたことがある。学校から帰るとすぐに中のよい友人と通話状態にして、とくに話すことがなくても常につなぎっ放しにしているというようなものだった。

思えば、自分の世代は小中のころは、FAXがそういった役割を担っていた。中のよい友人とFAXでいろいろなやり取りをしていた。当然通話料がかかるが、電話をつなぎっぱなしよりも継続的なコミュニケーションがとれた。FAXを欲しいとこのとき以上に思ったことはなかった。高校のときは、携帯メールで、いつのまにか知らない話題が周囲で共有されていることに気づき、またも携帯がほしくなったものだった。大学時代のコミュニケーションの中心はmixiWindows Messengerだった。Skypeをつなぎっぱなしで、家にいながら友人と飲み会をしたのは大学院の頃。

それぞれのメディアで、「あるあるネタ」が生まれては消えていった。それはその世代そのときにしか感じられない経験であった。そういったコミュニケーションを介在するサービスに関わりたいと思ったのは、そういったさまざまな原体験に基づいているのかもしれない。

先の中学生のコミュニケーションスタイルを自分は追体験できていない。NintendoDSですれ違い通信をしたり、公園でバトルしている子供たちに自分はなることはできない。モンハンを同僚と楽しむのとはまた別の何かがあるはずだと思う。

同じように自分の体験を前の世代が体験することができていない。そこに認知不協和を呼ぶことがあるのだろう。実際年を取るにつれて、今現在の若いユーザのコミュニケーションのあり方を認識するのが難しくなるという感覚はある。そこに恐怖がある。自分の感覚の貯金を切り崩していく感覚だ。

30代、40代で今現在をとらえている人はとても少ない。そういった希有な人に決まって聞くのはどうやって、今現在をとらえているんですか?という質問だ。答えも要約すれば一つに決まっている。若い人と話すことだ。と。

これには少しばかりの反駁も合った。もう少し論理的なアプローチがあるのではないか。分析的、定量的に今現在を知るというアプローチもあるのではないかと。大筋は今でもそう思っている。だが、実際の所どうだろうか。統計因果関係を表すものではないのだから、これにも限界があることは少し考えればわかることだ。エビデンスを積むことはできても、そもそもその契機となる仮説構築プロセスは感覚や体験によるものだ。

気がつけば、高校生から10年経っている。貯金がつきるのもカウントダウンが始まっている。このカウントダウンが終わった後、自分の手に残っているものを考えて、日々電車に揺られている。