mixiのアーキテクチャパターン
2011年4月現在、
システムの境界と階層化
mixiでは個々の機能について、
- Mixi::Voice::*
つぶやき機能に関するモジュール群
- Mixi::Video::*
ビデオ機能に関するモジュール群
- Mixi::Diary::*
日記機能に関するモジュール群
- Mixi::Home::*
ホーム表示機能に関するモジュール群
以降では、
システム自体が大きくなり、
階層化
そのためmixiではコンポーネント間の連携とその手段を制限していく方針を決めました。
まず始めに、
- <<application>>
1つの機能を実現するために必要なモジュール群
- <<framework>>
システム横断的に利用するユーザデータの取得手段
- <<service>>
<<application>>間の連携の仲介を行うパッケージ
- <<common library>>
<<application>>、
<<service>>に依存しないユーティリティ
これらは図1の結合のみを許すようにしています。この階層化の定義によって、

以降では、
設定ファイルによる依存性注入
<<service>> に相当するコンポーネントは、
疑似RPCによるコンポーネント間連携
Perlでは一般に、
では、
そこで、
この擬似的なRPCは、
- blessされたオブジェクトやコードリファレンスを受け付けない
- システム横断でユニークな名前が付与できる
- その処理の名前と実行するパッケージ名の紐づけをYAML
(YAML Ain't Markup Language) で記述する
といった特徴を持っています。
---
methods :
getEntryBody : Mixi::Voice::Adapter::Entry
insertComment: Mixi::Voice::Adapter::Comment
deleteComment: Mixi::Voice::Adapter::Comment
insertFeedback: Mixi::Voice::Adapter::Feedback
deleteFeedback: Mixi::Voice::Adapter::Feedback
my $result =
Mixi::Service::Procedure::InternalGateway->call(
'jp.mixi.voice.insertComment' => {
owner_id => $xxx,post_time => $yyy
}
);
システムでユニークな名前を持っていることは、
また、
記述に手間がかかりますが、
また、
Q4Mを用いたPub/Sub
サービスが拡大するにつれて、
次のような関数の例を見てみましょう。
sub add_entry {
my ($self,$user,$entry) = @_;
if( $user->is_official ) {
: 公認アカウントのための処理
}
if( $body->is_open ) {
: 全体公開日記のニュース登録
: カスタマーサポートのための登録
: 特徴語抽出
: タイアップのための処理
}
: 友人フィードへの書き出し
: 各種キャッシュクリア
# 本来書きたい処理
$self->db->insert_diary( $user->id ,$entry->body);
}
ユーザが日記を投稿するときに実行される関数内で、
UserEventを利用すると、
sub add_entry {
my ( $self, $user ,$entry ) = @_;
$self->db->insert_diary( $user->id ,$entry->body);
fire Mixi::UserEvent('diary.create',{
diary_id => $entry->id,
member_id => $user->id,
body => $entry->body,
title => $entry->title
});
}
このようにシステム内でユーザが行った行動のCRUD
このイベント時に実行する処理をシステムの設定ファイルに次のように記述します。
# handlers
---
- Mixi::Official::YYY # 公認アカウントの処理のハンドラ
- Mixi::CS::XXX # CS系処理のハンドラ
- Mixi::Feed::ZZZZ # フィード系処理のハンドラ
---
# parameter interface
body : required
member_id : required
title : required
group_id : optional
各種ハンドラは、
このしくみによって、
単体テストによる境界の明確化
上述のような<<service>>に分類されるしくみを採用することで、
UserEvent、
自分と他人の境界をはっきりさせることで、