Groovyのすべてのクラスは暗黙的にgroovy.lang.GroovyObjectインタフェースを実装していて、GroovyObjectインタフェースにはMOP用のメソッドが定義されている。
こんな感じ。シンプル。
invokeMothod
set/getProperty
set/getMetaClass
→groovy.lang.MetaClass imprements MetaObject
コード例
まとめ
grooby++
かねこ\(^o^)/
2012年10月14日日曜日
2012年9月14日金曜日
Jenkins先生とIRCの連携の巻
IRCサーバうごいたので、早速Jenkinsのビルド結果をIRCサーバに送ってみよう。
JenkinsにはIRC Pluginがあるので導入。
Jenkinsの管理→プラグインの管理→Jenkins IRC Plugin
「Jenkinsの管理」→「システムの設定」にIRC Nortification発見!有効に。
ビルドしてみる…jenkins-botきた!わーい
いや、なんかしろ(笑)
気を取り直して設定見直し。
プロジェクト単位の設定の方にあった。
JenkinsにはIRC Pluginがあるので導入。
Jenkinsの管理→プラグインの管理→Jenkins IRC Plugin
「Jenkinsの管理」→「システムの設定」にIRC Nortification発見!有効に。
ビルドしてみる…jenkins-botきた!わーい
いや、なんかしろ(笑)
気を取り直して設定見直し。
プロジェクト単位の設定の方にあった。
再度ビルド。
できたー!連携サイコー!
IRC用のちっちゃいモニター欲しい。
かねこ( ^ω^ )
2012年9月10日月曜日
MVCとMOVE
世間ではMVC is dead, it's time to MOVE on.(和訳)の話題が花盛り♪
ちょっと見てみた。
これの、too much code into your controllers, because~ の下り、イマイチ(><)
実際は、MVCのモデルの領域は、”データと手続き”の部分なので、Controllerが誇大化する場合は、そもそもModelの扱い方を間違えてるのではないかと思います(よくあるのは、ControllerからDAO操作してるとか)
ということで、MVC死んでねー
MOVEは一読してよくわからなかったので、次回お勉強してみようと思います。
かねこ( ・`д・´)
ちょっと見てみた。
MVC is a phenomenal idea. You have models, which are nice self-contained bits of state, views which are nice self-contained bits of UI, and controllers which are nice self-contained bits of …
What?
I'm certainly not the first person to notice this, but the problem with MVC as given is that you end up stuffing too much code into your controllers, because you don't know where else to put it.
これの、too much code into your controllers, because~ の下り、イマイチ(><)
実際は、MVCのモデルの領域は、”データと手続き”の部分なので、Controllerが誇大化する場合は、そもそもModelの扱い方を間違えてるのではないかと思います(よくあるのは、ControllerからDAO操作してるとか)
ということで、MVC死んでねー
MOVEは一読してよくわからなかったので、次回お勉強してみようと思います。
かねこ( ・`д・´)
2012年4月9日月曜日
MongoDB(5) シャーディング
今日はMongoDBのシャーディングをやってみよう。
shardingとは: Shard(database_architecture)
mongoのシャーディング: Sharding
はじめにデータベース起動(とりあえず3つ)
コンフィグサーバ起動
ルーティングプロセス起動
(デフォルトチャンクサイズは200MBだけど、テストのために3MBに指定)
ここまでで、サーバ群起動完了。
次に、shardingの設定をする。
mongo起動、adminデータベースに接続
shardサーバ追加
ステータス確認
shardキーを指定
おこられた(><)
データベースにsharding許可を指示
再度挑戦
ていうか、これ、コレクション単位でshardできるのか。すごい柔軟。
ルーティングサーバに接続して、テストデータ投入。
100万件くらい、いれればいいかな。
状況確認
状況確認2
100万件はいってる。
接続先を個別のデータベースに変えて確認
合計100万件はいってる。ナイス。
というわけで、MongoDB編おしまい。
かねこ( ;∀;)
shardingとは: Shard(database_architecture)
mongoのシャーディング: Sharding
はじめにデータベース起動(とりあえず3つ)
mongod --dbpath=d:\xampp\mongodb\data\shard1 --port 28017mongod --dbpath=d:\xampp\mongodb\data\shard2 --port 28018mongod --dbpath=d:\xampp\mongodb\data\shard3 --port 28019
コンフィグサーバ起動
mongod --configsvr --port 28099 --dbpath=d:\xampp\mongodb\data\config
ルーティングプロセス起動
(デフォルトチャンクサイズは200MBだけど、テストのために3MBに指定)
mongos --configdb localhost:28099 --port 28100 --chunkSize 3
ここまでで、サーバ群起動完了。
次に、shardingの設定をする。
mongo起動、adminデータベースに接続
D:\xampp\mongodb\bin>mongo localhost:28100/admin
MongoDB shell version: 2.0.3
connecting to: localhost:28100/admin
shardサーバ追加
mongos> db.runCommand({addshard:"localhost:28017"});
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> db.runCommand({addshard:"localhost:28018"});
{ "shardAdded" : "shard0001", "ok" : 1 }
mongos> db.runCommand({addshard:"localhost:28019"});
{ "shardAdded" : "shard0002", "ok" : 1 }
ステータス確認
mongos> db.rintShardingStatus();
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{ "_id" : "shard0000", "host" : "localhost:28017" }
{ "_id" : "shard0001", "host" : "localhost:28018" }
{ "_id" : "shard0002", "host" : "localhost:28019" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
mongos>
shardキーを指定
mongos> db.runCommand({shardcollection:"test.test",key:{userid:1}});
{ "ok" : 0, "errmsg" : "sharding not enabled for db" }
おこられた(><)
データベースにsharding許可を指示
mongos> db.runCommand({enablesharding:"test"});
{ "ok" : 1 }
再度挑戦
mongos> db.runCommand({shardcollection:"test.test",key:{userid:1}});
{ "collectionsharded" : "testdb.test", "ok" : 1 }
ていうか、これ、コレクション単位でshardできるのか。すごい柔軟。
ルーティングサーバに接続して、テストデータ投入。
D:\xampp\mongodb\bin>mongo localhost:28100
MongoDB shell version: 2.0.3
connecting to: localhost:28100/test
mongos>
100万件くらい、いれればいいかな。
mongos> for(var i =0; i<1000000; i++) {
... var doc = {userid:i, name:"user"+i};
... db.test.save(doc);
... }
状況確認
mongos> db.runCommand({addshard:"localhost:28017"});db.printShardingStatus();
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{ "_id" : "shard0000", "host" : "localhost:28017" }
{ "_id" : "shard0001", "host" : "localhost:28018" }
{ "_id" : "shard0002", "host" : "localhost:28019" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "testdb", "partitioned" : true, "primary" : "shard0000" }
{ "_id" : "test", "partitioned" : true, "primary" : "shard0000" }
test.test chunks:
shard0000 8
shard0001 7
shard0002 14
too many chunks to print, use verbose if you want to force print
状況確認2
mongos> db.test.count();
1000000
100万件はいってる。
接続先を個別のデータベースに変えて確認
D:\xampp\mongodb\bin>mongo localhost:28017
MongoDB shell version: 2.0.4
connecting to: localhost:28017/test
> db.test.count();
162515
D:\xampp\mongodb\bin>mongo localhost:28018
MongoDB shell version: 2.0.4
connecting to: localhost:28018/test
> db.test.count();
171400
D:\xampp\mongodb\bin>mongo localhost:28019
MongoDB shell version: 2.0.4
connecting to: localhost:28019/test
> db.test.count();
666085
合計100万件はいってる。ナイス。
というわけで、MongoDB編おしまい。
かねこ( ;∀;)
2012年3月26日月曜日
MongoDB(3) クエリ速習
クエリに挑戦!
サンプルデータ
全件検索
条件検索
ソート(昇順)
ソート(降順)
リミット
オフセット
リミット&オフセット(ページング)
条件演算子(条件演算子一覧はここ)
カーソル
まとめ
MongoDBのクエリー単純で簡単。
かねこ(~_~)
サンプルデータ
> db.example.remove() > for(var i =0; i<6; i++) { ... var doc = {name:'user'+i, point: i*1000}; ... db.example.save(doc); ... } >
全件検索
> db.example.find() {"_id":ObjectId("4f69766ea84ad157af92c6ab"),"name":"user0","point":0} {"_id":ObjectId("4f69766ea84ad157af92c6ac"),"name":"user1","point":1000} {"_id":ObjectId("4f69766ea84ad157af92c6ad"),"name":"user2","point":2000} {"_id":ObjectId("4f69766ea84ad157af92c6ae"),"name":"user3","point":3000} {"_id":ObjectId("4f69766ea84ad157af92c6af"),"name":"user4","point":4000} {"_id":ObjectId("4f69766ea84ad157af92c6b0"),"name":"user5","point":5000}
条件検索
> db.example.find({point:2000}) { "_id" : ObjectId("4f69766ea84ad157af92c6ad"), "name" : "user2", "point" : 2000 }
ソート(昇順)
> db.example.find().sort({point:1}) { "_id" : ObjectId("4f69766ea84ad157af92c6ab"), "name" : "user0", "point" : 0 } { "_id" : ObjectId("4f69766ea84ad157af92c6ac"), "name" : "user1", "point" : 1000 } { "_id" : ObjectId("4f69766ea84ad157af92c6ad"), "name" : "user2", "point" : 2000 } { "_id" : ObjectId("4f69766ea84ad157af92c6ae"), "name" : "user3", "point" : 3000 } { "_id" : ObjectId("4f69766ea84ad157af92c6af"), "name" : "user4", "point" : 4000 } { "_id" : ObjectId("4f69766ea84ad157af92c6b0"), "name" : "user5", "point" : 5000 }
ソート(降順)
> db.example.find().sort({point:-1}) { "_id" : ObjectId("4f69766ea84ad157af92c6b0"), "name" : "user5", "point" : 5000 } { "_id" : ObjectId("4f69766ea84ad157af92c6af"), "name" : "user4", "point" : 4000 } { "_id" : ObjectId("4f69766ea84ad157af92c6ae"), "name" : "user3", "point" : 3000 } { "_id" : ObjectId("4f69766ea84ad157af92c6ad"), "name" : "user2", "point" : 2000 } { "_id" : ObjectId("4f69766ea84ad157af92c6ac"), "name" : "user1", "point" : 1000 } { "_id" : ObjectId("4f69766ea84ad157af92c6ab"), "name" : "user0", "point" : 0 }
リミット
>db.example.find().limit(2) { "_id" : ObjectId("4f69766ea84ad157af92c6ab"), "name" : "user0", "point" : 0 } { "_id" : ObjectId("4f69766ea84ad157af92c6ac"), "name" : "user1", "point" : 1000 }
オフセット
> db.example.find().skip(4) { "_id" : ObjectId("4f69766ea84ad157af92c6af"), "name" : "user4", "point" : 4000 } { "_id" : ObjectId("4f69766ea84ad157af92c6b0"), "name" : "user5", "point" : 5000 }
リミット&オフセット(ページング)
> db.example.find().skip(2).limit(2) { "_id" : ObjectId("4f69766ea84ad157af92c6ad"), "name" : "user2", "point" : 2000 } { "_id" : ObjectId("4f69766ea84ad157af92c6ae"), "name" : "user3", "point" : 3000 }
条件演算子(条件演算子一覧はここ)
> db.example.find({point:{$gte:3000}}) { "_id" : ObjectId("4f69766ea84ad157af92c6ae"), "name" : "user3", "point" : 3000 } { "_id" : ObjectId("4f69766ea84ad157af92c6af"), "name" : "user4", "point" : 4000 } { "_id" : ObjectId("4f69766ea84ad157af92c6b0"), "name" : "user5", "point" : 5000 }
カーソル
> var cursor = db.example.find(); > cursor.hasNext() true > cursor.next() { "_id" : ObjectId("4f69766ea84ad157af92c6ab"), "name" : "user0", "point" : 0 } >while (cursor.hasNext()){printjson(cursor.next());} { "_id" : ObjectId("4f69766ea84ad157af92c6ac"), "name" : "user1", "point" : 1000 } { "_id" : ObjectId("4f69766ea84ad157af92c6ad"), "name" : "user2", "point" : 2000 } { "_id" : ObjectId("4f69766ea84ad157af92c6ae"), "name" : "user3", "point" : 3000 } { "_id" : ObjectId("4f69766ea84ad157af92c6af"), "name" : "user4", "point" : 4000 } { "_id" : ObjectId("4f69766ea84ad157af92c6b0"), "name" : "user5", "point" : 5000 }
まとめ
MongoDBのクエリー単純で簡単。
かねこ(~_~)
2012年3月21日水曜日
MongoDB(1) 導入編
MongoDBやります。いい加減、やっとかないとまずい状況です。
特長
・ドキュメント志向(JSON)
・スキーマレス
・簡単なレプリケーション
・自動シャーディング
・高速
・トランザクション機能なし
とか。
とりあえず、環境準備めんどくさいからWindows環境(+XAMPP)で使えるようにしてみる。
どうせクロスプラットフォームだし。
1.ダウンロード
公式サイトよりダウンロード
2.展開と設置
展開して、置けばおしまい。
ディレクトリ構成例
3.きどう
コマンドプロンプトで、デーモン起動
ログを見ると、
4.PHPとの連携
続いて、PHPにドライバを設定してPHPと連携させてみる。
MongoDBネイティブドライバのインストール説明ページのとおり。
該当のdllダウンロードして、php.iniに設定。
まとめ
MongoDB超簡単。
かねこ( `д´)
特長
・ドキュメント志向(JSON)
・スキーマレス
・簡単なレプリケーション
・自動シャーディング
・高速
・トランザクション機能なし
とか。
とりあえず、環境準備めんどくさいからWindows環境(+XAMPP)で使えるようにしてみる。
どうせクロスプラットフォームだし。
1.ダウンロード
公式サイトよりダウンロード
2.展開と設置
展開して、置けばおしまい。
ディレクトリ構成例
D:\xampp\mongodb ┗bin ┗data ┗log
3.きどう
コマンドプロンプトで、デーモン起動
D:\xampp\mongodb\bin>mongod --logpath=D:\xampp\mongodb\log\mongodb_log.txt --dbpath=D:\xampp\mongodb\data
ログを見ると、
Mon Mar 19 17:18:58 Mon Mar 19 17:18:58 warning: 32-bit servers don't have journaling enabled by default. Please use --journal if you want durability. Mon Mar 19 17:18:58 Mon Mar 19 17:18:58 [initandlisten] MongoDB starting : pid=4688 port=27017 dbpath=D:\xampp\mongodb\data 32-bit host=e2info9 Mon Mar 19 17:18:58 [initandlisten] Mon Mar 19 17:18:58 [initandlisten] ** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data Mon Mar 19 17:18:58 [initandlisten] ** see http://blog.mongodb.org/post/137788967/32-bit-limitations Mon Mar 19 17:18:58 [initandlisten] ** with --journal, the limit is lower Mon Mar 19 17:18:58 [initandlisten] Mon Mar 19 17:18:58 [initandlisten] db version v2.0.3, pdfile version 4.5 Mon Mar 19 17:18:58 [initandlisten] git version: 05bb8aa793660af8fce7e36b510ad48c27439697 Mon Mar 19 17:18:58 [initandlisten] build info: windows sys.getwindowsversion(major=6, minor=0, build=6002, platform=2, service_pack='Service Pack 2') BOOST_LIB_VERSION=1_42 Mon Mar 19 17:18:58 [initandlisten] options: { dbpath: "D:\xampp\mongodb\data", logpath: "D:\xampp\mongodb\log\mongodb_log.txt" } Mon Mar 19 17:18:59 [initandlisten] waiting for connections on port 27017 Mon Mar 19 17:18:59 [websvr] admin web console waiting for connections on port 28017 Mon Mar 19 17:19:59 [clientcursormon] mem (MB) res:14 virt:44 mapped:0 Mon Mar 19 17:19:59 [PeriodicTask::Runner] task: WriteBackManager::cleaner took: 31ms
ちゃんと動いてるっぽい(64bit推奨)。
27017が標準ポート。
Windowsのサービスとして登録する場合は、「--install」
以上。
27017が標準ポート。
Windowsのサービスとして登録する場合は、「--install」
D:\xampp\mongodb\bin>mongod --install --logpath=D:\xampp\mongodb\log\mongodb_log.txt --dbpath=D:\xampp\mongodb\data
以上。
MongoDBの導入超簡単。
4.PHPとの連携
続いて、PHPにドライバを設定してPHPと連携させてみる。
MongoDBネイティブドライバのインストール説明ページのとおり。
該当のdllダウンロードして、php.iniに設定。
extension=php_mongo.dll
以上。
MongoDBドライバの導入も超簡単。
まとめ
MongoDB超簡単。
2011年12月5日月曜日
おさらい(1)ソフトウェア内部アーキテクチャ
さて、勢いにのってガリガリとコードを書きたかったのですが、そんな時間はありませんでした。
なので、そういえば書きたかったシステムの設計について書いてみようと思います。
だいいちだん、ソフトウェア内部構造のまき。
ちなみにこれは、某Challenging Tomorrow's Changesな会社のSFAシステム構築プロジェクトに僕とまっちゃんコンビで参画したときに、お師匠のたなかみつるさんに教えてもらったアーキテクチャで、わずか数ヶ月の間にみにつけたこの設計技法は、その後何年間もずーっと、僕のシステム設計思想のベースになっているものです。ありがとう、お師匠。げんきか、まっちゃん。
というわけで、絵をかいてみました。
- N層アーキテクチャは導入必須。層を分離しないとテストコードが書けない。
- テストコード必須。テストコード書かないと、機能追加の際に一定ライン以上の品質を保証することができません。あと、漠然とした不安につきまとわれます。
- 基本的にMVCパターンの適用は必須で、要件と複雑さに応じて層を設計します。上の図は中間規模の業務システムを構築するときに設計のベースとしているMVC+Serviceでの設計。もう少し大規模になると、サービス層と永続化層の間にLogic層を挟むことを検討する。
- View層(プレゼンテーション層)にはテンプレートエンジンを導入。JavaだとVelocityとかFreeMarker、PHPはSmartyなど。PHP自体がテンプレートエンジンだけど、そのレベルでは保守性からみてダメで、ちゃんと処理・データとテンプレートが分離されている必要がある。
- Controller層では、View層(ブラウザ)からのリクエストを受け取って、ビジネスロジックに繋ぐ。Controllerにはビジネスロジックは記述しない。1画面(や、1機能)に対して1コントローラが存在する設計(P of EAAのPage Controllerパターン)と、システム内で一つのコントローラがすべてのリクエストをハンドリングする方法(P of EAAのFront Controllerパターン)があって、別にどっちでもいい。
- Service層(ロジック層)は、Session Facadeとして定義。トランザクションを意識した設計にする。
- 永続化層は、どの言語でもすぐれたフレームワークがたくさんあるので導入する。種類が色々あるので特性を理解して選定する。というか、実は選定はどれでもよくて、メンバーに特性を理解させることが重要。
- DaoとEntityにMockオブジェクトを定義するのは、Service層の自動テストを書くときにMockオブジェクトを利用したテストを実行するため。あとは、ビルドパラメータでmock/releaseの切り替えできるようにしておくことで、データベースに接続できない環境で画面を動かすことができる。
- また、某所では、サービス層のMockオブジェクトも定義するルールになっていて、プレゼンテーション層とロジック部分の開発の切り離しをしていた。これも上手くまわっていた。
- 上図にでてきていない部分としては、例外設計とログ設計重要。ちゃんとやる。あと、パターンの理解重要。同じ用語と概念でシステムについての会話ができるようになる。
そんなこんなで、なんでこんなことするかというと、すべては「テストを書きやすくするため」です。
TDDまでいかなくても、テストまで書くサイクルがきちんと回っているプロジェクトの場合、そうでないプロジェクトと比較すると品質がとてもよいです。経験上。
TDDまでいかなくても、テストまで書くサイクルがきちんと回っているプロジェクトの場合、そうでないプロジェクトと比較すると品質がとてもよいです。経験上。
で、テストをちゃんと書くするために、層を分離しましょうということになります。その結果、コンポーネントの独立性がたかくなって、保守もやりやすくなる。まさに、いいことずくめ。
自動テスト実行、自動ビルド、構成管理、カバレッジ、メトリクス、コード規約、コードの自動精査など、他にもまだまだおもしろそうな話題がいろいろありますよ。
というわけで、つづく。
やっぱりコード書けばよかった。
かねこ( ´_ゝ`)
やっぱりコード書けばよかった。
かねこ( ´_ゝ`)
登録:
投稿 (Atom)