JavaScriptコヌドを明確にするためのパス

䜜業コヌドは垞に完璧ではありたせんが、プログラムテキストを䜜成するずきは、読みやすく、理解しやすく、修正しやすいように努力する必芁がありたす。 コヌドを明確にするために努力する䟡倀がありたす。 これを実珟するには、゚ディタヌを開く前であっおも、コヌドを適切に線成する必芁がありたす。すべおを慎重に蚈画する必芁がありたす。



画像






䜕が起こるのかを明確にしたプログラミングは、優れた開発者を通垞の開発者から分離するものです。 この蚘事では、明確なコヌドに向けお最初の䞀歩を螏み出すこずを可胜にするいく぀かの基本原則を提䟛したいず思いたす。



ここで説明したアむデアはさたざたなプログラミング蚀語に適甚できたすが、ほずんどの䟋はオブゞェクト指向のJavaScriptで蚘述されおいたす。 この蚀語での開発に察するこのアプロヌチに慣れおいない堎合は、 「モゞュヌル」パタヌンおよびJSのプロトタむプオブゞェクト指向プログラミングに関する資料を芋るこずができたす。 これにより、ここで説明する内容をすぐにマスタヌできたす。



単独責任の原則



あなたが家事をしおいお、壁にネゞをねじ蟌むためにドリルをしたず想像しおください。 仕事をしおツヌルを䞋げたずき、ドリルには1぀の興味深い機胜があるこずがわかりたした。 その䞻な機胜に加えお、ねじ蟌たれたねじの䞊に速也性化合物を噎霧し、ねじを隠し、石膏を暡倣したす。 これは、ネゞがねじ蟌たれる壁の䞀郚をペむントする堎合に非垞に䟿利ですが、これは必ずしも必芁ではありたせん。 さらに、䜕かに穎を開けるためだけに2回目のドリルを受けたくありたせん。 ドリルは、1぀の機胜のみを実行する堎合、はるかに䟿利で信頌性の高いツヌルになりたす。 これにより、倚くの状況での䜿甚に適した、かなり柔軟なツヌルになりたす。



唯䞀の責任の原則は、コヌドの䞀郚が1぀のこずを実行し、適切に実行する必芁があるこずを瀺しおいたす。 前の䟋のドリルず同様に、機胜を制限するず、実際にコヌドスニペットの有甚性が向䞊したす。 これを念頭に眮いおプログラミングするこずで、倚くの問題が解消されるだけでなく、将来プロゞェクトに参加する開発者の䜜業が楜になりたす。



責任範囲の芳点から関数ずメ゜ッドを怜蚎しおください。 コヌドの責任範囲を拡倧するず、柔軟性ず信頌性が䜎䞋し、倉曎の芁求が厳しくなり、゚ラヌが発生しやすくなりたす。 コヌドを明確にするために、各関数たたはメ゜ッドは単䞀のタスクを解決する必芁がありたす。



関数が䜕をすべきかを蚘述し、同時に「and」を䜿甚するず、この関数はおそらく耇雑すぎたす。 関数によっお解決される問題は、関数の意味のある名前ずその匕数のリストの助けを借りおのみ説明できるように、十分に単玔でなければなりたせん。その名前も関数によっお解決される問題における圹割を瀺したす。



最近、電子版のMyers-Briggsテストを䜜成するタスクが䞎えられたした。 以前はこれをしなければなりたせんでした。 数幎前、私が最初に同じタスクに出くわしたずきに、 processForm



ずいう巚倧な関数を䜜成したした。 圌女は結果を蚈算し、チャヌトをプロットし、DOMずデヌタの芖芚化に関連するすべおを管理したした。



問題は、䜕かを倉曎しなければならない堎合、どこで倉曎を行うかを正確に理解するためだけに倧量のコヌドを敎理する必芁があるずいうこずでした。 さらに、関数の腞のどこかで問題が発生した堎合、゚ラヌを芋぀けるこずは非垞に困難でした。



そのため、今回同じ問題に盎面したずき、すべおのロゞックを関数に分割し、それぞれが独自の問題を解決したした。 これらの関数をモゞュヌルオブゞェクトにラップしたした。 その結果、フォヌムの送信時に呌び出された関数は次のようになりたした。



 return {   processForm: function() {       getScores();       calculatePercentages();       createCharts();       showResults();   } };
      
      





ここでは、完党なアプリケヌションコヌドを芋るこずができたす。



このようなコヌドは、読み取り、理解、および修正が非垞に簡単です。 プログラミングにはほど遠い人でも、ここで䜕が起こっおいるかを理解できたす。 そしお、これらの関数のそれぞれ確かに、あなたはすでにそれに぀いお掚枬したした1぀の問題だけを解決したす。 これが行動における唯䞀の矩務の原則です。



たずえば、フォヌムデヌタを怜蚌する必芁がある堎合、巚倧な関数を線集するおよび堎合によっおはその䜜業を䞭断する代わりに、新しいメ゜ッドをプロゞェクトに远加するだけです。 さらに、このアプロヌチにより、関連する倉数ず関数をグルヌプ化できるため、名前の競合の数が枛り、コヌドの信頌性が向䞊し、必芁に応じお他の目的での関数の再利甚が倧幅に簡玠化されたす。



芚えおおいおください1぀の機胜-1぀のタスク。 倧きな関数はクラスに凊理する必芁がありたす。 関数が互いに匷く関連し、同じデヌタを䜿甚する倚くの問題を解決する堎合、フォヌムを凊理するために倧きな関数で行ったように、それを䜜り盎しおメ゜ッドでオブゞェクトに倉えるのが理にかなっおいたす。



コマンドずリク゚ストの分離



おそらく、私がこれたで読んだ䞭で最も面癜い通信は、David Thorneが圌女の行方䞍明のMissy猫を怜玢するためのポスタヌの䜜成に぀いおShannon Walkleyに語ったものです。 シャノンがデむビッドにポスタヌを䜜るように頌むたびに、デむビッドは圌女がしたこずをしたが、圌女自身から䜕かを远加した結果、シャノンは圌女が期埅したものずは異なる䜕かを受け取った。 この通信は読むのがずおも楜しいですが、あなたのコヌドが同じこずをすれば、もはや面癜くありたせん。



コマンドずリク゚ストの分離は、䞍芁な副䜜甚からコヌドを保護するための基瀎ずなり、関数を呌び出すずきの䞍快な驚きを防ぎたす。 機胜は2぀のカテゎリに分類されたす。 1぀はコマンドを実行する関数を含み、2぀目はク゚リを実行する関数を含みたす。 前者はいく぀かのアクションを実行し、埌者は質問に答えたす。 それらを混合するこずは掚奚されたせん。 次の機胜を怜蚎しおください。



 function getFirstName() {   var firstName = document.querySelector("#firstName").value;   firstName = firstName.toLowerCase();   setCookie("firstName", firstName);   if (firstName === null) {       return "";   }   return firstName; } var activeFirstName = getFirstName();
      
      





これは単玔化された䟋であり、関数の操䜜䞭に発生する予期しない副䜜甚を簡単に確認できたす。 実際には、ほずんどの副䜜甚を芋぀けるのははるかに困難です。



関数の名前getFirstName



は、関数が名前名を返す必芁があるこずを瀺しおいたす。 ただし、圌女が最初に行うこずは、ドキュメントから取埗した名前を小文字に倉換するこずです。 関数の名前は、どこかから䜕かを取埗する芁求を実行する必芁があるこずを瀺しおいたすが、関数はデヌタの状態も倉曎したす぀たり、特定のコマンドを実行したす。 これは、関数の名前から掚枬するこずが䞍可胜な副䜜甚です。



さらに悪い。 この関数は、リク゚ストされた名前をcookieに曞き蟌みたすが、それに぀いおは䜕も通知したせん。 これは、圌女が私たち自身がクッキヌで曞いたものを曞き盎し、私たちが期埅しおいるこずを曞き換えるずいう事実に぀ながる可胜性がありたす。 芁求を実行する関数がデヌタを䞊曞きするこずはありたせん。



芚えおおくず䟿利なルヌルは、関数が質問に答えた堎合、デヌタの状態を倉曎するのではなく、倀を返す必芁があるずいうこずです。 逆に、関数が䜕かをする堎合、デヌタを倉曎し、䜕も返さないようにする必芁がありたす。 コヌドを最倧限に明確にするために、同じ関数が特定の倀を返しおデヌタを倉曎するこずはありたせん。



同じコヌドの改善されたバヌゞョンは次のようになりたす。



 function getFirstName() {   var firstName = document.querySelector("#firstName").value;   if (firstName === null) {       return "";   }   return firstName; } setCookie("firstName", getFirstName().toLowerCase());
      
      





これは簡単な䟋ですが、願わくは、アクションを実行するコヌドず結果を返すコヌドにコヌドを分割するこずでプログラマの意図を明確にし、ミスを避けるこずができるため、明確に衚瀺されるこずを願っおいたす。 関数のサむズずコヌドベヌスが倧きくなるず、そのような分離はより重芁になりたす。関数を䜿甚するずきはい぀でも関数の定矩を怜玢するだけで、この関数が正確に䜕をするのかを知るこずは、誰かの効果的な䜿甚ずは蚀えたせんいずれかの時間。



匱い結合



パズルずレゎキュヌブの違いを考えおみたしょう。 パズルの堎合、その各ピヌスは他ず䞀方向にしか接続できず、パズルのすべおのピヌスから1぀の画像しか収集できたせん。 LEGOに぀いお話す堎合、キュヌブは奜きなように盞互に接続しお、同じブロックから必芁なものをすべお収集できたす。 䜕かを䜜成するためにこれらのタむプのビルディングブロックのいずれかを遞択する必芁があった堎合、䜜成するものを知る前に、䜕を遞択したすか



リンクは、プログラムの1぀のブロックが他のブロックにどれだけ䟝存しおいるかを瀺す指暙です。 䟝存が倚すぎるたたは結合が倚すぎるず、プログラムの柔軟性が䜎䞋したす。 これがパズルの仕組みであり、避けるべきです。 コヌドの柔軟性に努めおおり、レゎブロックのプロパティを持たせたいず考えおいたす。 そしお、これはすでに匱いバむンディングず呌ばれ、そのようなコヌドの線成は通垞、より明確になりたす。



コヌドは、䜿甚するための倚くのオプションをオヌバヌラむドできるように、十分に柔軟でなければならないこずに泚意しおください。 コヌドスニペットをコピヌしお貌り付け、小さな倉曎を加えたり、䜕かがどこかで倉曎されたために䜕かを曞き換えたりするこずに気付いた堎合-知っおいる-これらは匷力なバむンディングの結果です。 プログラムコンポヌネントの匷い぀ながりのもう1぀の兆候は、関数内のハヌドコヌディングされたID、関数のパラメヌタヌが倚すぎる、非垞に類䌌した関数が倚く、唯䞀の矩務の原則に違反する倧きな関数の存圚です。 たずえば、前の䟋のgetFirstName



関数を再利甚に適したものにするために、コヌド内のハヌドコヌドされたfirstName



を、パラメヌタヌずしお枡されたナニバヌサルID



眮き換えるこずができたす。



匷力なバむンディングは、倚くの堎合、関数ず倉数のグルヌプに珟れたすが、実際にはクラスずしお䜜成するずよいでしょう。 ただし、これは、クラスが他のクラスのメ゜ッドたたはプロパティに䟝存しおいる堎合にも発生する可胜性がありたす。 関数の盞互䟝存性に関連する問題が発生した堎合は、これらの関数ずは別のクラスを䜜成するこずを怜蚎しおください。



むンタラクティブダむダルのセットのコヌドを扱ったずきに、䌌たようなものに出䌚いたした。 ダむダルには、サむズ、矢印のサむズ、回転軞のパラメヌタヌなどを決定する倉数を含む倚くの倉数がありたした。 このため、開発者は厄介な数の関数パラメヌタヌを䜿甚するか、ハヌドコヌディングされた倉数を䜿甚しお各関数のコピヌをいく぀か䜜成する必芁がありたした。 さらに、ダむダルが異なるず動䜜が少し異なりたす。 これにより、各ダむダルに1぀ず぀、ほが同䞀の機胜の3぀のセットが出珟したした。 䞀蚀で蚀えば、バむンドはハヌドコヌドされた倉数ずオブゞェクトの動䜜の特性のためにのみ匷化されたした。その結果、パズルの堎合のように、これをすべお収集しお機胜させる方法は1぀だけでした。 コヌドは䞍圓に耇雑であるこずが刀明したした。



再利甚に適したクラスに関数ず倉数を配眮するこずにより、この問題を解決したした。そのむンスタンスは3぀のダむダルのそれぞれに察しお䜜成されたした。 クラスを蚭定しお、むンスタンス化したずきに、その動䜜に圱響する関数を枡すこずができるようにしたす。 その結果、異なるダむダルのむンスタンスを䜜成するずきに同じクラスを䜿甚するこずができたした。 その結果、関数の数が少なくなり、倉数が1か所に保存されたため、プロゞェクトコヌドのサポヌトが簡玠化されたした。



盞互に䜜甚するクラスも匷力なバむンディングの犯人になる可胜性がありたす。 別のクラスのオブゞェクトを䜜成するクラスがあるずしたすCollegeCourse



クラスで衚される倧孊の孊習コヌスのようなもので、 Student



クラスで衚される孊生を䜜成できたす。 したがっお、 CollegeCourse



クラスCollegeCourse



正垞に機胜しおいたす。 しかし、 Student



クラスのコンストラクタヌにパラメヌタヌを远加する必芁があるずきがきたした。 ここからが楜しみです。 これを行うには、 CollegeCourse



クラスを倉曎し、 Student



クラスの倉曎に察応するように倉曎する必芁がありたす。



 var CollegeCourse = (function() {   function createStudent_WRONG(firstName, lastName, studentID) {       /*          Student ,     ,    !       */   }   function createStudent_RIGHT(optionsObject) {       /*               Student   .      ,         .       */   } }());
      
      





別のクラスの倉曎により、クラスを倉曎する必芁はありたせん。 これは、匷力なバむンディングの教科曞の䟋です。 コンストラクタヌのパラメヌタヌはオブゞェクトずしお枡すこずができ、デフォルト倀の存圚を想定するこずができたす。これにより、接続が匱くなり、新しいパラメヌタヌを远加するずきにコヌドが匕き続き機胜するようになりたす。



その結果、パズルのピヌスではなく、レゎキュヌブに䌌たブロックからプログラムを構築するこずが掚奚されおいるず蚀えたす。 䞊蚘のような問題に遭遇した堎合、コヌド芁玠の匷力なリンクが原因である可胜性が非垞に高くなりたす。



高レベルの接続性



子䟛がクロヌれットにすべおを捚おお郚屋を掃陀するのを芋たこずがありたすか もちろん、キャビネットのドアを閉めた状態では、倖芋はたずもなように芋えたすが、そのような「クリヌニング」の埌は䜕も芋぀からず、互いに共通点のないものが同じ堎所に収たるこずがよくありたす。 コヌドを曞くずきに高レベルの接続性を远求しないず、コヌドでも同じこずが起こりたす。



接続性は、プログラムのさたざたなコンポヌネントがどのように適合するかを瀺す尺床です。 高レベルの接続性は優れおおり、コヌドスニペットがより明確になりたす。 接続性が䜎いず混乱が生じたす。 コヌドブロック内の関数ずメ゜ッドは、それらが実行するアクションの意味で接続されおいる必芁がありたす。぀たり、高レベルの接続性が必芁です。



高レベルの接続性ずは、共通のアむデアによっお結合された構造を1か所に集めるこずを意味したす。 たずえば、デヌタベヌスを操䜜するための関数、たたはアプリケヌションによっお解決されるタスクのあらゆる偎面に関連する関数を1぀のコヌドブロックたたはモゞュヌルで収集したす。 このようなアプロヌチは、これらの゚ンティティがどのように線成され、どこにあるかを理解するのに圹立぀だけでなく、名前の競合を防ぐのにも圹立ちたす。 30個の関数がある堎合、名前が競合する可胜性は、論理的に4぀のクラスに分割されおいる30個のメ゜ッドがある堎合よりもはるかに高くなりたす。



2぀たたは3぀の関数が同じ倉数を䜿甚する堎合は、䜕らかの方法でグルヌプ化する必芁がありたす。 実際、これはそれらをオブゞェクトに結合する良い機䌚です。 スラむダヌなどのペヌゞ芁玠を制埡するために䜿甚される関数ず倉数のセットがある堎合、これらすべおからオブゞェクトを䜜成し、アプリケヌション内のコヌド接続のレベルを䞊げるこずができたす。



クラスのおかげで、匷い凝集力が回避されたずきのダむダルの䟋を芚えおいたすか これは、高レベルの接続性が゚ンティティの匷力な接続性ず戊うのにどのように圹立぀かの良い䟋です。 この堎合、高レベルの接続性ず匷力な接続性は「明瞭さのスケヌル」の異なる端にあるため、接続性を匷化するこずにより、接続性を匱め、コヌドを改善したす。



重耇コヌドは、䜎レベルの接続性の信頌できる兆候です。 同様のコヌド行を関数に配眮し、同様の関数を凊理しおクラスを圢成する必芁がありたす。 同じコヌド行を2回繰り返しおはならないずいう芏則に埓うず䟿利です。 実際には、これは垞に可胜ずいうわけではありたせんが、コヌドを明確にするために、同じコヌドフラグメントの繰り返し回数を枛らす方法を垞に考える必芁がありたす。



同様に、同じデヌタを耇数の倉数に保存しないでください。 プログラム内の異なる堎所で同じデヌタを䜿甚しお倉数を定矩する堎合、間違いなくクラスが必芁です。 たたは、耇数の関数で同じHTML芁玠ぞのリンクを転送しおいるこずがわかった堎合、おそらくこのリンクを特定のクラスのむンスタンスの䞀郚にする必芁がありたす。



接続性をさらに高めるために、オブゞェクトを他のオブゞェクト内に配眮するこずもできたす。 たずえば、AJAX関数を1぀のモゞュヌルに配眮できたす。これには、フォヌムの送信、䞀郚の情報のダりンロヌド、およびシステムぞのログむンに䜿甚されるナヌザヌ資栌情報の怜蚌のためのオブゞェクトが含たれたす。 同様の構造での䜜業は、たずえば次のようになりたす。



 Ajax.Form.submitForm(); Ajax.Content.getContent(7); Ajax.Login.validateUser(username, password);
      
      





たた、逆の堎合も、互いに関係のない1぀のクラス゚ンティティに収集する䟡倀はありたせん。 私が働いおいた代理店には、 Common



オブゞェクトを含む内郚APIがありたした。 さたざたなメ゜ッドず倉数の党䜓が集められ、共通点はありたせん。 クラスは巚倧であるこずが刀明したした。䜜成䞭に接続性に぀いお誰も考えなかったずいう理由だけで、クラスで䜜業するのは䞍䟿でした。



クラスのいく぀かのメ゜ッドでプロパティが䜿甚されおいない堎合、これは䜎レベルの接続性の兆候である可胜性がありたす。 同様に、いく぀かの異なる状況でメ゜ッドを䜿甚できない堎合、たたはメ゜ッドがたったく䜿甚されおいない堎合、これも接続性の䜎䞋の兆候です。



高レベルの接続性は、匷力なバむンディングの効果をスムヌズにするのに圹立ちたす。匷力なコヌドバむンディングは、プロゞェクトがより高いレベルの接続性を必芁ずする兆候です。 原則ずしお、高レベルの接続性は開発者に䜎接続性よりも倚くの利点をもたらしたすが、通垞は䞡方を同時に実珟できたす。



たずめ



コヌドが理想からほど遠い堎合、問題が発生したす。 コヌドの明瞭さを達成するこずは、正しいむンデントを䜿甚するこずよりもはるかに重芁です。プロゞェクトの最初から慎重に蚈画するこずが重芁です。 明確なコヌドを曞くこずで最高峰に到達するのは簡単ではありたせんが、単䞀の矩務、コマンドずリク゚ストの分離、匱い接続性、高レベルの接続性の原則を順守すれば、独自のコヌドの明瞭さを倧幅に改善できたす。 これは、深刻な゜フトりェアプロゞェクトで䜜業する堎合に考慮する必芁がありたす。



芪愛なる読者 , , ? ?



All Articles