Javascriptアプリケーションのスケーラビリティの基盤

「早く行きたいなら一人で行きましょう。遠くまで行きたいなら一緒に行きましょう。」 (c)







この記事のこの歌詞の行から、アプリケーション内でコードを適切に編成して、コードの高さと幅を拡大する方法について説明します。 脳の活動の成果物を競合他社の成果物よりも強力にしたい場合は、チームに新しいプログラマーを招待する必要があります。 そして、スケーラビリティのベクトルを配置しないと、1年で熱意の爆発がコードヌードに変わり、チームワークがすべての従業員を怒りから小さなサタンに変えます。







だから...あなたの戦闘機が1つのプロジェクトで一緒に快適に感じるためには、彼らがお互いに干渉せず、コードの異なる重複しないセクションに文字を書くことが必要です。 これを行うには、「スタンドアロン」コンポーネントを作成する必要があります。







「独立」-これらは、外部環境からのイベントに焦点を合わせて、それ自体が動作を制御するコンポーネントです。 アプリケーションがどのように動作し、どのようなイベントが発生するかについての知識があれば、コードの古い部分や他の部分に影響を与えることなく、そのような「独立した」コンポーネントを簡単に作成できます。







「非自己完結型」-外部環境については何も知らないが、非常に詳細なAPIを持つコンポーネント。 このコンポーネントは、アプリケーションでの動作方法を説明する必要があります。 このようなコンポーネントは、「スタンドアロン」コンポーネントとは異なり、githubなどのオープンライブラリなど、プロジェクトまたはパブリックプロジェクトで再利用できるように作成されています。







アプリケーションで必要なコンポーネントを判断する方法は? とても簡単です。 コンポーネントが1つのタスクのみに適用可能であり、再利用できない場合は、「独立」するように記述する必要があります。

たとえば、チャットストリームのメッセージ入力フィールドを表すコンポーネントを考えます。 ほとんどの場合、アプリケーションでそのような入力フィールドを使用するのは意図された目的だけであり、たとえば承認時にニックネームやパスワードを入力するという形では使用しません。コンポーネントには独自の特性があるためです。







遅延する価値がないという事実のために猫を引っ張ることはせず、特定の例を分析します。 チャットルームを模したものにしましょう。







チームに2人のプログラマーがいるとします。 ペトカとトーリック。 そして、彼らはスケーラブルなアプリケーションの中核を持っています。 2本指の男の2本の指のように簡単です。 カーネルには、ネットワークトランスポート、配列形式のメッセージフィードストレージ(この例ではメソッドを備えた個別のファイルとして選択しません)、およびイベントエミッターがあり、この場合はスケーラビリティの鍵となります。

この例のイベントエミッタとして、Backbone.Eventsを使用しましたが、これはBackboneを使用して例をできるだけ簡単に示すことに限定されています。







<html> <head> <script src="http://underscorejs.org/underscore-min.js"> <script src="http://backbonejs.org/backbone-min.js"> <script src="connection.js"/> <script src="app.js"/> </head> <body> <div id="header" style="padding:10px; border:1px solid #ddd"></div> <div id="container" style="margin-top:20px;"></div> <script> var app = new App(); app.init(); app.on('new_message', function(text){ console.info('new message', text); console.info('messages length', app.messages.length); }); </script> </body> </html> //app.js var App = function(){ var app = _.extend({ init: function(){ this.connection.connect(); } }, Backbone.Events); app.connection = new Connection(), app.messages = []; app.connection.on('connected', function(){ console.info('App connected!'); }); app.connection.on('incoming_message', function(text){ app.messages.push(text); app.trigger('new_message', text) }); return app; } //connection.js var Connection = function(){ return _.extend({ connect: function(){ /*  ,                  */ var i=0; setInterval(_.bind(function(){ i++; var text = 'message_' + i; this.trigger('incoming_message', text); },this),1000); this.trigger('connected'); }, }, Backbone.Events); }
      
      





さて、これまでにビューがなく、ブラウザコンソールで作業をテストできるアプリケーションがあります。 ところで、アプリケーションからすべての補助コンポーネントとビューを削除し、コンソールを介して動作できる場合、これは非常に良いことです。 そのため、コンポーネントとコード間の弱い接続をある程度まで自動テストでカバーできます。 運転しました。







現在、戦略計画に精通している人は、タスクをPetkaとTolikに設定します。彼らは、アプリケーションがメッセージフィードを表示する必要があり、ヘッダーにはフィード内のすべてのメッセージのカウンターがあると言います。 あなたは質問があるかもしれません...誰がこれを必要としますか? これは単なる例です。







わかりました、ペトカとトーリック、わかりました。 彼らは、アプリケーションに対して2つの異なるコンポーネントを同時に記述することにしました。







Petkaはメッセージフィードのタスクを引き受けました



しかし、彼はスケーラブルなアプリケーションをプログラムする方法について聞いていなかったので、コードを書き始めました。







 //list-view.js - ""  var ListView = function(){ var el = document.createElement('div'); return { el: el, addMessage: function(text){ var row = document.createElement('div'); row.innerHTML = 'message: ' + text; el.appendChild(row); } } } //app.js   var App = function(){ var app = _.extend({ init: function(){ connection.connect(); } }, Backbone.Events); app.connection = new Connection(), app.messages = []; //  app.listView = ListView(); document.getElementById('container').appendChild(app.listView.el); // app.connection.on('connected', function(){ console.info('App connected!'); }); app.connection.on('incoming_message', function(text){ app.messages.push(text); app.trigger('new_message', text); app.listView.addMessage(text); //  }); return app; }
      
      





Petyaは、より高いレベルのメソッドで制御する必要があるコンポーネントを作成しました。その結果、コンポーネントを宣言するだけでなく、app.jsコードを掘り下げ、incoming_messageハンドラーに行を追加する必要がありました。 アプリケーションが壊れないように、「app.listView = ..」および「... appendChild(app.listView.el)」の行をコメントアウトすることはできません。 app.listView.addMessage(テキスト); 例外をスローします。 アプリケーションは接続性の中で成長し始めました。 カーネルはビューに依存し始めました。







ヘッダーのメッセージカウンターでTolikがタスクにどのように対処したかを見てみましょう



彼は他人を邪魔しないようにコードを書く方法を知っています。







 //header-view.js var HeaderView = function(app) { var el = document.createElement('div'), span = document.createElement('span'), view = { el: el, setCounter: function(num){ span.innerHTML = num; } } el.innerHTML = '- : '; el.appendChild(span); view.setCounter(0); app.on('new_message', function(){ view.setCounter(app.messages.length); }); return view; } //app.js   ... app.connection = new Connection(), app.messages = []; //  app.headerView = HeaderView(app); document.getElementById('head').appendChild(app.headerView.el) // ...
      
      





Tolikが彼のコンポーネントの範囲外で行ったことは、アプリ変数領域でコンポーネントを宣言し、すべてをレンダリングすることでした。 このコンポーネントは、引き続きAPIを返すため、コンソールを介した手動テストまたは単体テストでも使用できます。

Tolikコードの責任範囲は、本質的に1つのheader-view.jsファイルのみに制限されており、これらの編集は1つのファイルだけを見る必要があるため、レビューが容易です。







「スタンドアロン」コンポーネントの作成は有益です



Tolikが自己完結型でないコンポーネントも作成した場合、app.jsでPetyaと同じコードに影響を与えていたでしょう。 制御が難しく、コンポーネント間の接続が増加します。 このような小さな例では、これはあまり目立たないかもしれませんが、合計で数千のコードがあり、大規模で複雑な機能が記述されている場合、それをよく感じることができます。

コードを記述するプロセスでは、常に、より高いレベルの階層でコンポーネントを管理するか、コンポーネントを個別に管理するかの選択があります。

紳士を分けて支配し、アプリケーションに「独立した」コンポーネントを作成します。







psこの記事のコード例は、フレームワークを使用せずにベアJSで記述されていますが、この弱結合の哲学は、バックボーンまたはReluxやReduxなどの同形アプリケーションのトリッキーな方法論との反応、または他のフレームワークを使用する場合にも有効です。

プログラマが新しい機能を見ているときは、コードの責任範囲を制限するように常に努めてください。 Reactなどのレンチが与えられた場合、ナットを締める必要があります。指で叩く必要はありません。







JivoSite.ru開発チームは、クリーンでわかりやすいコードを希望しています。








All Articles