Single Level of Abstraction (SLA) [Principles Wiki]
SLAPとはSingle Level of Abstraction Principleの略で直訳して単一レベルの抽象化原則です。上記リンクはSLAですが、SLAPの方が検索結果が多いです。この原則をもっとかみ砕いていうと、プログラムの構造化の段階を揃えましょう、となります。これが為されていると読みやすくまとまったコードが出来ます。例えば次のようなコードです。
function 高水準(){// レベル1の目次 中水準1(); 中水準2(); } function 中水準1(){// レベル2の目次-1 低水準1(); 低水準2(); } function 低水準1(){// 本文内容 // 処理 } function 低水準2(){// 本文内容 // 処理 } function 中水準2(){// レベル2の目次-2 低水準3(); } function 低水準3(){// 本文内容 // 処理 }上田勲. プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則 (Kindle の位置No.946-956). 株式会社秀和システム. Kindle 版.
例は書籍の内容に沿って処理を行うコードになっています。書籍で言う目次、章、節がそれぞれ高水準、中水準、低水準に従う形です。こうなっていると、どこで何のために何をしているか分かりやすくなります。
高水準─┬─中水準1─┬─低水準1 │ └─低水準2 └─中水準2───低水準3
少々極端ですが、もし共通する部分をまとめて扱うことを優先し次の様になっていた場合、どこからどこまでが何のための処理なのかわかりにくくなります。
// 低水準1,2,3で使う変数の宣言 // 低水準1と3の共通前処理 // 低水準1の処理 // 低水準2の処理 // 低水準2と3の共通処理 // 低水準3の処理 // 低水準1と3の共通後処理
最初の例では本の内容をコードに落とし込むため幾分か楽に構造化レベルを整えられましたが、実際は処理の長さの差がまちまちでなかなかまとめるのが難しくSLAPを完全に守ることができないこともあります。そういった時、SLAPの上で最低限守るべきなのは呼び出し時のレベルの統一です。次の様にすると何もしない時よりか幾分楽に読めるようになります。
function 高水準(){// 目次 中水準1(); 中水準2(); 中水準3(); } function 中水準1(){// 章-1 低水準1(); 低水準2(); } function 低水準1(){// 節-1 極低水準1(); 極低水準2(); 極低水準3(); } function 極低水準1(){// 本文内容 // 処理 } function 極低水準2(){// 本文内容 // 処理 } function 極低水準3(){// 本文内容 // 処理 } function 中水準2(){// 章-2 本文内容 // 処理 } function 中水準3(){// 章-3 低水準3(); } function 低水準3(){// 節-2 本文内容 // 処理 }
上記例が読み難い原因はいずれも同レベルfunctionで宣言されているためです。例えばJavaScriptの関数内関数でレベル分けをするならば次の様になります。
function 高水準(){// 目次 中水準1(); 中水準2(); 中水準3(); } function 中水準1(){// 章-1 低水準1(); 低水準2(); function 低水準1(){// 節-1 極低水準1(); 極低水準2(); 極低水準3(); function 極低水準1(){// 本文内容 // 処理 } function 極低水準2(){// 本文内容 // 処理 } function 極低水準3(){// 本文内容 // 処理 } } function 低水準2(){// 節-2 本文内容 // 処理 } } function 中水準2(){// 章-2 本文内容 // 処理 } function 中水準3(){// 章-3 低水準3(); function 低水準3(){// 節-3 本文内容 // 処理 } }
読みやすくなりました。この書き方そのままではネストが深くなってしまいますが実際にはフォルダ、ファイル、クラス、プロパティ、アクセス修飾子などによる分類も用いて構造化を行うことで、深いネストの回避とレベルの統一された階層化を実現します。
高水準─┬─中水準1─┬─低水準1─┬─極低水準1 │ │ ├─極低水準2 │ │ └─極低水準3 │ └─低水準2 ├─中水準2 └─中水準3───低水準3