🤯

Swift.orgのAPI Design Guidelinesから関数名の命名についてチャートにする

3 min read

はじめに

この文章は書籍Effective Swiftのための下書きの一部の項目「はじめに」をアルファ版として公開してみます。

私の勘違いがあったりするかもしれません。できればコメントください。

なお、下書きのためこちらのタイミングで非公開にすることはあります。

関数名

Swiftは簡潔さよりも明確さが重要視されています。その理由として1つの関数を記述するのは一度だけですが、繰り返し何度でも人間が読み取ることになるためです。その明確さのためにSwiftでは引数にラベルをつけられるのですが、どのような関数の命名をすべきか迷うことがあるでしょう。

この章はAPI Design Guidelinesについて解説します。

命名についての検討図

関数を命名していく際に検討するための項目をUMLのアクティビティ図として表現しました[1]

修正したい場合、PlantUMLのコードをどうぞ
!pragma useVerticalIf on
start
!pragma useVerticalIf on
start
if (イニシャライザ?) then (Yes)
    if (変換?) then (Yes)
        if (ナローイング変換?) then (Yes)
            :変換のための\n絞り込み方法をラベルとする;
            stop
        else (No: ワイドニング変換)
            :ラベルを省略する;
            stop
        endif
    else (No)
        :ラベルはプロパティ名のまま;
        stop
    endif
(No) elseif (Factoryメソッド?) then (Yes)
    :makeではじめる;
    :ラベルはプロパティ名のまま;
    stop
else (No)
    if (引数なし) then (Yes)
        if (副作用なし?) then (Yes)
            :メソッドではなくプロパティ\nを使うことを検討する;
            stop
        else (No: 副作用ある)
        endif    
    else (No)
        if (引数が複数?) then (Yes) 
            if (引数が複数あり区別する必要がある?) then (Yes)
                :前置詞をラベルとして区別することを検討する;
                if (前置詞だけで\n関数の意図を説明しきれる?) then (No)
                    :前置詞句をラベルにすることを検討する;
                else (Yes)
                endif
            (No) elseif (引数が複数あり区別する必要がない?) then (Yes)
                :すべてのラベルを省略する;
            (No) elseif (複数の引数が1つの前置詞に対して必要?) then (Yes)
                :前置詞をメソッドに含ませる;
            endif
        else (No)
            if (前置詞なしで流暢な英語のような関数名?) then (Yes)
            else (No)
                :前置詞をラベルに\n使うことを検討;
                if (前置詞だけで\n関数の意図を説明しきれる?) then (No)
                    :前置詞句をラベルにすることを検討する;
                else (Yes)
                endif
            endif

            if (不必要な繰り返しのある\n関数名になってる?) then (Yes)
                :引数が繰り返していれば\n省略することを検討する;
            else (No)        
            endif

            if (引数が弱い型付け?) then (Yes)
                :関数名で\n引数の役割を\n補足;
            else (No)
                if (引数の意味を\nラベルで伝える必要ある?) then (Yes)
                    :ラベルで補足することを検討する;
                else (No)
                endif
            endif

        endif
        
        if (副作用なし?) then (Yes: 副作用はない)
            partition 副作用がないメソッド {
                if (すでにmutateメソッドがあり\n作成しようとしているのは\nnon mutateメソッド?) then (Yes)
                    if (名詞での表現が自然?) then (Yes)
                        :作成済みのmutateメソッドを\nfromで始めるように変更、\n新たに作成する\nメソッドを名詞とする。;
                        stop
                    else (No)
                        :ed/ingルール;                
                        stop
                    endif
                else (No)
                    :副作用を\n持たない関数は\n名詞句を検討する;
                    stop
                endif     
            }
        else (No: 副作用ある)
        endif
    endif
endif

partition 副作用があるメソッド {
    if (すでにnon mutateメソッドがあり\n作成しようとしているのは\nmutateメソッド?) then (Yes)
        if (名詞での表現が自然?) then (Yes)
            :新たに作成するmutateメソッドを\nfromで始めるようにする。;
            stop
        else (No)
            :ed/ingルール;                
            stop
        endif
    else (No)
    endif

    :命令形の動詞句とすることを検討する; 
    stop
}
脚注
  1. とりあえず図示をしたかったので手軽なplantUMLのアクティビティ図を選んでしまって、アクティビティ図は適していないかもしれません。 ↩︎

Discussion

ログインするとコメントできます