nodeJSでかなりの数のアプリケーションを研究した結果、何らかの理由で、ほとんどのPHPフレームワークで現在受け入れられているMVCパターンをほとんど使用しないことに気付きましたが、このモデルは非常に便利であり、作成にかかるコスト(最初は非常に深刻です)実を結ぶでしょう。
実際のプロジェクト
タスクは私のために設定されました-node.jsにゲーム機のアプリケーションサーバーを実装することは、非常に簡単に思えます。 これをやった人からたくさんのコードをもらいました。 データベースとして、Redisが使用されます。 アプリケーションの構造は次のようになりました。
-ルート
--application.js
--config.js
--constants.js
--import_data.js
--slots_module.js
--user_activity.js
--social.js
--node_modules /
---ここにnode.jsのモジュールがあります
ノードのかなり馴染みのある構造ではありませんか? :=)
しかし、アプリケーションの要件が増大し、あらゆる種類の機能の量が増えると、予想されるように、このアプリケーションの保守が非常に難しくなりました。 アプリケーションと構成はそれぞれ5,000行になり、多くのコードの複製やその他の楽しみがあり、プロジェクトの検索を使用しないと、どこにあるかを判断することはほとんど不可能になりました。
そして最後に、私たちは要点に来ました。 沸騰します。 アプリケーションの徹底的なリファクタリングと再編成を行うことにしました。 まず、オブジェクトリレーショナルマッピング(ORM)のようなものがあることを思い出し、驚いたことに、NodeJSとRedisのORMのかなり良い実装を見つけました。 これは、私にとって馴染みのあるアーキテクチャを使用する大きな推進力となりました。 nohmモジュールを使用すると、モデル、そのプロパティ、およびメソッドを非常に簡単に記述できるため、コードを削減し、より構造的で美しいものにすることができます。 以下は、ユーザーモデル(User.js)の説明と使用の簡単な例です。
/** * User: hlogeon * Date: 31.07.13 * Time: 23:36 * TODO: continue creating this * read http://maritz.github.io/nohm/ */ var nohm = require('nohm').Nohm; var redis = require('redis').createClient(); nohm.setClient(redis); nohm.model('User', { properties: { balance: { type: "integer", defaultValue: 0, index: false }, ad_id: { type: "string", index: true }, bonus_games_pending: { type: "boolean", index: false }, chips: { type: "integer", defaultValue: 0 }, source: { type: "string" }, spins_count: { type: "integer", defaultValue: 0 }, mute: { type: "boolean", defaultValue: false }, sound: { type: "boolean", defaultValue: false }, charges_base: { type: "boolean", defaultValue: false }, parent_ref: { type: "string", index: true }, sid: { type: "string", index: true }, bonus_to: { type: "integer", defaultValue: 0 }, points_count: { type: "integer" }, parent_id:{ type: "string", index: true }, invitation_accepted: { type: "string" }, ref_type: { type: "string", index: true }, spins_temporary: { type: "integer" }, enter_date: { type: "integer" }, free_spins: { type: "integer" }, screen: { type: "string" }, last_game: { type: "string" }, startOffer: { type: "boolean", index: true }, last_activity: { type: "integer" }, win_turn: { type: "integer" }, double_game_pending: { type: "integer" }, level: { type: "integer", index: true }, last_spin: { type: "integer" }, uid: { type: "string", index: true }, status: { type: "string" }, bonus_games_temporary: { type: "integer", defaultValue: 0 }, browser: { type: "string" }, builded: { type: string, } }, methods: { getContryFlag: function () { return 'http://example.com/flag_'+this.p('country')+'.png'; }, updateBalance: function (value){ var balance = this.p('balance'); this.p('balance', balance+value); this.save(); }, updateChips: function(value){ var chips = this.p("chips"); this.p("chips", chips+value); this.save(); }, incrSpins: function(){ var spins = this.p('spins_count'); this.p('spins_count', spins+1); this.save(); }, swichMute: function(){ var mute = this.p('mute'); this.p('mute', !mute); this.save(); }, swichSound: function(){ var sound = this.p('sound'); this.p('sound', !sound); this.save(); }, setPointsCount: function (value){ this.p('points_count', value); this.save(); return value; }, incrPointsCount: function(){ var count = this.p('points_count'); this.p('points_count', count+1); this.save(); }, incrSpinsTmp: function(){ var tmp = this.p('spins_temporary'); this.p('spins_temporary', tmp+1); this.save(); }, incrFreeSpins: function(){ var spins = this.p('free_spins'); this.p('free_spins', spins+1); this.save(); }, incrLevel: function(){ var level = this.p('level'); this.p('level', level+1); this.save(); return this.p('level'); } } }); var user = nohm.factory('User'); exports.user = user;
使用例:
var user = require('./UserTest').user; app.get('/', function (req, res) { // var activeUser = nohm.factory('User'); activeUser.save(function(errs){ if(errs){ // , res.json(errs); } else{ // , res.json(activeUser.allProperties()); } }); // -? app.get('/findUser', function (req, res) { var id = req.body.id; // user.load(id, function(err, aUser){ if(err){ // , ! res.json(err); } else{ // , - , ! console.log(aUser.getCountryFlag()); res.json(aUser.allProperties); } }) });
同意します。これは定数redis.hgetall()よりもはるかに簡単です。特に、モデルやリレーションでユーザーメソッドを定義できるようになったためです。
このアプローチのおかげで、アプリケーションをモジュールに分割し、新しい構造は次のようになります。
-ルート
--application.js
--constants.js
--config.js
-モデル/
--- User.js
--- Slotmachine.js
--- Event.js
-ヘルパー/
--- Social.js
--node_modules /
さらにいくつかのファイルがありましたが、コードサポートが大幅に簡素化され、行数が大幅に減少し、読みやすさが驚くほど向上しました! これで、10レベルのネストのコールバック関数から麺を解く必要はありません。 すべてが透明で、シンプルで明確です。
nodejsの初心者からのこの小さな記事が誰かに役立つことを願っています。 批判に非常に感謝します!