1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

2.7 名前重要

プログラミングだけでなく、命名は意図がわかりやすいとか、
コミュニケーションギャップをなくす上でも非常に重要なものである。

ドメイン駆動設計などにおける、概念モデリング時に考えた【ユビキタス言語】
これはまさにこの思想を取り入れて臨まなければならない。

良い名前が見落としていたコンテキストの境界を発見したりすることもある。

なぜ名前が重要なのか?

まずは簡単に名前を大事にしないことで起きた痛いエピソードのお話しをします。

名前を重要視していなかった頃の痛い話

これは最初「名前なんか多少雑でもいいでしょ~」くらいに高をくくっていた
私は痛いほどその理由がわかります。
モデリングをしていて、名前をそこまで重要視できていなかった当初
数日経過してからそのモデル図を見た際、
「あれ? なんでこの名前つけたんだっけ? この属性ってどういう意味だっけ?」
という事態が発生しました。
しかもそのモデルは、自分で作成したものであるにもかかわらず です。

おかげでそこから再度モデルの議論をするために、2、3時間も時間を無駄にしました。

コードに負債を抱えてしまうから

上記の私のエピソードは、モデル図で抽象化されていたから、
まだソースコードほど細かい情報を読み解く必要はないから数時間で済ませることができました。

仮にもしも実際のソースコード上で同じことをやっていたら、
あまたの詳細な情報という枝葉を再度読み解き、解析しないと全体像を把握できないという
自体を引き起こし、下手したら数日時間を浪費していたことでしょう。

関数名を見ただけで、容易に処理の詳細な内容を類推できるほど。
モジュール名をみて、すぐにどのコンポーネント内にある要素か?
をすぐに言い当てられるほど 名前からして意図がわかりやすい状態でないと、
解析するだけで無駄に認知負荷がかかってしまい、
本来の価値あるコードを書くことに専念しにくくなってしまいます。

すると今度は

開発生産性の低下

開発者体験の低下

などの嬉しくない状態を招くことになります。

どのような場面で重要になってくるか?

意識したいポイント

これはPIE原則などとの関連もある。
さらに他のSLAPなどやKISSなどと密接にかかわっているものである。
良い名前であるからこそ、抽象度を揃えやすくなるし、シンプルさにも繋がる。
逆にSLAPだからこそ、よい名前を付けやすくなるという相互に関係しあう。

また操作の名前付けだけでなく、エンティティ名やコンポーネント名、サービス名、
さらにはそれらの粒度感まで把握しやすい名前付けが重要となる。

そのためには、チーム内または時にはチームの境界を飛び越えて、
他のチームと共同でモデリングを継続的に行うことでユビキタス名を発見するのをお勧めします。

ステークホルダーの命名

書籍では触れられていないが、ステークホルダーの命名も端的かつ潜在的な要求やその者(外部システムの場合もある)が欲しい情報などを類推しやすい命名を意識すると、変なところに操作やデータを割り当てるリスクを減らせる。

これはステークホルダーモデリングや要求分析ツリーを作成しながら、
徐々に名前を洗練していくのが現実的であると感じます。

最初からめちゃくちゃいい名前を見つけるというのは、そもそも対象のステークホルダーの潜在的な価値を見つけ出せていないうちは無理と思った方がいいです。

ちなみにこのステークホルダーの命名は、PMさんと必ず行いましょう!
なんでかというと、PMさんが使う外部の利害関係者の名前と、
開発者などが使う名前がずれた状態ですと、コミュニケーションギャップが起きて、
大幅な手戻りの原因になったりします。

インターフェイス命名における名前設計

インターフェイスの設計は以前の記事で解説したように、
下位の具象でオーバーライドするすべての処理の事前事後条件を満たすという、
契約による設計を意識した帰納的な設計が求められる。

これは決して容易なことではなく、一度定義したインターフェイスに対して、
変更せざるを得ないような仕様変更が入ることだってある。
その際に意識しておいた方がいい点を以下に示す。

Fat Interface

インターフェイスが持つロジックが増えてきて、多目的なインターフェイスになってしまった際に、インターフェイス分離の原則が適用できるようなケースである。
ここですぐにインターフェイスを1つの目的となるように分割する決断をするのはまだ早い。

そのインターフェイスに依存したクライアントプログラムが、どの程度の不利益を被るかを考慮していないからだ。
しかしかといって何もしないのは非常に見通しも悪い状態なままだ。

そこでもしも1つの単一目的となるように分割できなくても、
「このインターフェイスには複数の目的が混在しています」という意図の伝わりやすい名前であること、
および 「無理に単一目的にできない時には、命名で複数目的と理解できるようにする」
というコード規約によって、対象のインターフェイスがどの程度多目的か理解しやすい。

事例

たとえば、再生・早送り・巻き戻し・停止・一時停止するという
処理から構成されたDVDプレイヤーというインターフェイスがあるとする。

対して、再生・早送り・巻き戻し・停止・一時停止する 以外にも、
録画・ダブルで録画・予約録画・ダブルで予約録画する という9つの処理を持つ
DVDレコーダーというインターフェイスがあるとする。

補足

また多目的と分かりやすい名前にするだけでなく、「なぜ多目的なのにinterface分離の原則に従わないのか?」の理由をADRとして残しておくなどすると、さらにチーム全体の設計力向上にもつながりやすい。

ループバックチェック

良い名前を付けるために、非常に武器になる手法として、ループバックチェックもあります。
これは超重要なテクニックであり、以下の記事でも触れている。

それだけでなく、以下のようなケースでも使用できる。

クラス名の命名

まずはクラス名だけを見て、属性リストを隠し、中にどんな属性があるのかを類推する。
今度は属性のリストを見て、クラス名を隠し、どんな名前が妥当なのかを考える。
属性が必要十分になっているかのチェックもおおよそ可能である。

もしもその属性の集合に対して、複数の意図の名前を付けられる状態になっていたら、
そのクラスには複数の責務が混在している危険性があります。

クラスというミクロな単位では、あえて複数の責務にしてしまうというのも手ですが、
より大きな粒度感のコンポーネントにおいて、多目的になった状態は、
変更時のコストが跳ね上がるなどのリスクを考えると避けた方がいいでしょう。

パッケージ名の命名

上記の属性をクラス、クラス名をパッケージ名に対応させて同じことをする。
ドメインモデリングはある意味トップダウンでモジュールに命名をしている。
対して、ボトムアップでも命名の良さを検証しないといけない。

クラス群の集合に対して、どのような名前を付けられるのか?
パッケージ名を隠しながらつけてみる。
もしも最初につけた名前と一致していないのなら、まだ制度が甘いということだ。

この流れは上記のクラス名への命名と似たプロセスである。
パッケージ以上の粒度感のコンポーネントに対しても、このプロセスは同じである。

ロジックへの命名

上記2つでは、データの構造的なところに着目してループバックチェックを行いました。
しかしながら、モジュールの持つロジックに対してのループバックチェックも大事です。

処理の名前を隠した状態で、処理の詳細内容を読んでみて、
どんなロジック名を付けられるのか?をチェックします。

ここでもしも詳細内容が、足し算したり、真偽判定したりして、
結局どんなロジック名を付けたらいいのか悩むという状態は、
そのロジックが複数のロジック責務を持った状態の可能性が高いです。
そのような場所は、1つの責務になるように切り分けた方がいい箇所です。

そして、外からと内側から両方からチェックします。

外側から見てチェック

そのモジュールを外から使うモジュールから見て、公開されているロジックの集合に対して、たった1つの名前を付けることができるか?

それは、モジュールの公開するインターフェイスが単一目的かのチェックになります。

もしも使う側から見て、複数名前を付けられるような状態であったら
使われる方の対象モジュールは、その時点で多目的であり、単一責務に反しています。

内側から見てチェック

今度は対象モジュールだけに着目します。
それ以外のモジュールは一旦関心の外に追いやります。

その状態で、モジュールの持つロジックの集合に対して、
たった1つのモジュール名を付けることができるかをチェックします。

このときには、後に出てくる対称性も重要になってきますが、今回は長くなるので省きます。
もしも唯一の名前を付けられて、外側から見た時の名前と違和感がなければ、
ロジックの観点でのチェックは完了です。

外側から見た時の名前と内側から見た際の名前は一致するとは限りません。
なぜなら、内側から見て注文予約というモジュール名を付けられたとしても、
顧客というモジュールから見たら、予約履歴という意味になりうるからです。

後者はモデリングでは、関連端名といいますが、ここでは大事な論点ではないので端折ります。
大事なのは、その関連端名と内側から見た際に付けた名前とが矛盾がないか?
のチェックを行うことです。

データとロジック、両方からのチェック

先程のデータ構造でとらえた際に着けた名前と、ロジックの観点でつけた名前とを
比較してみてください。

明らかに意図が異なる、矛盾するという状態であった場合は、すぐに見直しましょう。

もしかしたら正しく処理が割り当てられていない可能性が高いです。

情報エキスパートでそうならないための対策はできますが、念のためにもこのチェックは必要です。

特にマイクロサービスにおけるテーブルの所有権を考えた後で、
再度マイクロサービスの名前を洗練したりするときなどに必須な考えです。

ループバックのおさらい

必ずこのループバックチェックによって、
情報構造の側面と、ロジック構造の側面両方から名前を洗練することで、
その時点におけるよい名前を付けることができる。

データの構造、クラスならば属性の集合に対して1つの名前を付けられるか?
コンポーネントならば、その中身にあるサブコンポーネントの集合に対して1つの名前を付けられるか?
という

情報構造の側面における唯一の名前を付けられるか?

それに+して、ロジックの側面でも同じことを行い、
付けたモジュール名の意図に矛盾がないか?のチェックを行うのです。

そこまで磨き上げることで、かなり洗練された名前を作り出すことができます。

なので、いかにこのループバックチェックをチームで素早く行うかが大事です。

今回第三回目のまとめ

SLAPにしてると、インターフェイスを用いた変動からの保護、OCPを満たしやすくなる。そのためには名前設計(名前空間含む)も重要であり、粒度や意図まで容易にわかる命名である必要がある。その名前の洗練のためには極力シンプルさを意識し、ムダなもの関連の薄いものを混ぜない対策と工夫が必要。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?