Indent Identity略してIndentity

# はじめに
この記事は社内用Advent Calendar 2014 の12/19分の記事です。
今年も特に社外秘な情報を扱うこともないので公開します。

ゆるふわっと、しかし、宗教論争が起きそうな内容になっていますが、気軽に読んで戴けたらと思います。
タイトルに深い意味はありません。

# 太陽曰く、整えよソース
先日、社内でデザイン研修が実施され、デザインの基礎を学ばせていただいた私。
意識してみると、色々なものが考えてデザインされていることに気づきます。

そこで私は思いました。
私が一番長時間見ているこいつらにも当てはまるじゃないか！と。

こいつらとは…？
そうです。
愛すべきクエリ達のことです。
いつもニコニコあなたの隣に這いよる混沌、ソースコードのことです。

# 実際にSQLで見てみる

SQLをこよなく愛してはいないけれども、インデントにはこだわりをもってやっている私のSQLをレイアウトの原則（近接、整列、コントラスト、反復）と照らしあわせて見てみましょう！（ちょっと長いです。）

```sql:MyQuery.sql

CREATE TABLE #MyTable
(
    ID          int
,   FirstName   varchar(20)
,   LastName    varchar(20)
,   Age         int
,   Gender      tinyint
,   BloodType   varchar(2)
)

INSERT INTO #MyTable
(
    ID
,   FirstName
,   LastName
,   Age
,   Gender
,   BloodType
)
VALUES
(
    1
,   '伊澄'
,   '宮村'
,   18
,   1
,   'A'
   
),
(
    2
,   '京子'
,   '堀'
,   17
,   2
,   'S'
)


SELECT
    18      AS Age
,   1987    AS BirthYear
INTO #BirthYear


DECLARE
    @SearchingAge       int     = 18
,   @SearchingGender    tinyint = 1

SELECT
    MAIN.ID             AS ID
,   FUNC.FullName       AS FullName
,   MAIN.Age            AS Age
,   FUNC.GenderName     AS GenderName
,   MAIN.BloodType      AS BloodType
,   BTYE.BirthYear      AS BirthYear

FROM #MyTable MAIN
LEFT OUTER JOIN #BirthYear BTYE
ON  BTYE.Age    = MAIN.Age
CROSS APPLY
(
    SELECT
        MAIN.LastName + ' ' + MAIN.FirstName    AS FullName
    ,   CASE Gender
                WHEN 1  THEN '男性' 
                WHEN 2  THEN '女性' 
                        ELSE '両性'
        END                                     AS GenderName
) FUNC

WHERE
    MAIN.Age    = @SearchingAge
AND MAIN.Gender = @SearchingGender

ORDER BY
    MAIN.ID
    

DROP TABLE #MyTable
DROP TABLE #BirthYear

```

## 近接
SQLでの切れ目で一番大きなものはステートメントの切れ目だと思います。
基本的にはステートメントの間は改行することで、一つのステートメントごとでの塊を自然と意識できるようになっているはずです。
特に処理の目的が変わるところでは2行改行を入れたりしています。（ワークの`INSERT`と`INSERT`の間や、その後の変数宣言との間など）
また、必要に応じてステートメントごとにコメントをつければ更に切れ目がわかりやすくなると思いますが、
今回はインデントの力だけでやってみています。

また、`SELECT`句と`FROM`句の間や`WHERE`句との間に1行改行を挟むことで、ここまでが項目、ここから取得元、ここからは条件とわかりやすい様に区切っています。

## 整列
カンマの位置、列名の開始位置、型の名前、イコールの位置、など、TAB（スペース4つ）区切りの先頭に来るようにしています。
矩形選択のやりやすさや、タイピングのしやすさから、最近は割と長い間この形で落ち着いています。
`JOIN`の`ON`句の後のスペースが2つでTAB区切りにしておくと、`AND`句が続いた時も頭が揃うのが気に入っています。
WHERE句も同様です。
また、`ORDER BY`や今回は無いですが`GROUP BY`も`SELECT`と同じ列で書くことで、行コピー&ペーストしてそのまま使えるのもこだわりポイントです。

## コントラスト
ここでは上手く見えてませんが、Microsoft SQLServer Management Studio様あたりだと、シンタックスハイライトがうまいこと働いているので、上手くコントラストができているかと思います。（他力本願。それしかない。）

余談ですが、なんで`INSERT`、`SELECT`、`DELETE`は青なのに`UPDATE`だけピンクなんでしょうか…
ご存知の方、教えてください。

## 反復
全体的にインデントの規則を統一させて書いているので、反復もできているかと思います。
また、自分が作るクエリはすべてこの書き方で書いているので、そういった意味でも反復できているかと思います。

システム全体でインデント規約的なものがあったほうが、デザインの基礎で出てきた「反復」を順守できるので、こういった規約も必要なのかなぁと思います。（もしかして弊社にはもう既にありますかね…？）

# 満足の結果
普段から意識してるインデントをレイアウトの原則と照らしあわせてみたら自分が読みやすいと思う理由が裏付けできて満足の結果が得られました。
読みやすい、書きやすいは人それぞれではあるかと思いますが、比較的多くの方に読みやすいと思ってもらえてるんじゃないかなーなんて自信も（無駄に）つきました。（実際のところどうかといった意見もお待ちしております…）

今回は載せませんでしたが、SQLだけでなく、他の言語でも意識してるポイントが皆さんそれぞれあると思います。
自分の書き方が原則にしたがっているか、確認してみると面白いかもしれません。

# まとめ

今更何言ってんだって話だったかもしれませんが、これって意外と暗黙知なんじゃないかなぁと思います。
形式知にしていく為にもこういった記事を書いてみてもいいかもしれないなぁと思い、テーマをこれにしました。(他にネタが思いつかなかった)

可読性の高いソースを書こう！とアチラコチラで言われています。
若手メンバーの中には「可読性の高いソースを書けるほど経験値がないよ…」って思っているメンバーもいるかもしれません。
ソースコードの一行一行に意味が求められるように、何気ない改行、タブ、スペースにも理由や意味があるソースは自然と読みやすくなると思います。
これを機に、改めてインデントについて、また、可読性について考えていけたらなぁと思います！

なお、「私のインデントが最高だ！！！」と私自身は思っていない…わけではなく、思っていますけど、「私のインデントはもっと美しい。」とか、「俺はインデントにこういうこだわりがあるんだ！」と思う方もたくさんいらっしゃると思います。
色々な意見があると思いますが、そういった議論が起こるのも面白いと思うので、是非自分の思想を発信して、洗練していきましょう！
ご意見、お待ちしております！

では、ここまで読んでくださってありがとうございました！