Skip to content

Instantly share code, notes, and snippets.

@udzura
Created June 16, 2020 09:48
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save udzura/a950b76ec122e30eee2ef09f1a49c6a1 to your computer and use it in GitHub Desktop.
Save udzura/a950b76ec122e30eee2ef09f1a49c6a1 to your computer and use it in GitHub Desktop.

自分がどういうことを考えてクラス設計しているかを整理してみました。同じようなことを大名エンジニアカレッジでも話したのですが、今回はフィヨルドの課題で考えてみました。

レイヤ分けする

たとえば ls コマンドの場合はこういうレイヤがあるんじゃないかなあと考えられます。

  • インプットする方法... OSの機能を使ってあるディレクトリのファイルを集めないといけない。その操作をする人が必要そう
  • 集まったデータ... ファイルが集まってくる。ファイルには、普通のファイル、ディレクトリの二種類はありそう。
  • アウトプット... 表示のフォーマットがいくつかある。一列のやつと、サイズなどを詳細に出すやつ。
  • それらをつなぐ... ここに書いていないあふれた仕事をとりあえず押し付ける人がいると便利かな...

Railsでいう「MVC」のようなノリですが、まずは自分でそういったレイヤを考察します。図を描くのもいいです。

データの流れがどうなってるか? などはこのレイヤ分けの参考になります。

関係性を考える

上のレイヤ分けから

  • FileCollector
  • NormalFile
  • Directory
  • OnelineOutput
  • DetailedOutput
  • Manager(...)

という風にクラスを抽出しました。これは暫定ではあります。

これらのクラスを:

  • 誰が誰を必要としているか?
  • 誰と誰が役割上「横並び」か?

という観点で関係を整理してみます(この観点は、本によって has_a is_a use_a などと呼ばれる概念に近いと思います)。

FileCollector ... File/Direcrotyを取得するのでその配列を持てると良さそう
NormalFile と Directory は横並び
OnelineOutput と DetailedOutput は横並び
  横並びなので親クラスがあっても良さそう
*OutputはデータとしてやっぱりFile/Direcrotyの配列が必要そう
Manager ... CollectorやOutputのメソッドを呼び出すので、参照を持ってないとダメそう

この関係性を考えると、「継承」という関係性が意外と出て来ないのも気づきになるかもしれません。

ここまできたら多分実装を始められるんじゃないかなあ? と思います。

その他留意したり思い出すこと

単体テストしやすいか考える

そのクラスが実装すべきメソッドや、クラスに必要な情報(依存、という言い方をする本もあります)がはっきりしているかなどを考えます。テストがしにくい場合、やっていることが複雑すぎたり、依存するオブジェクトが多い可能性があります。

依存でよく言われるのは:

  • なににも依存しない
  • 数値などに依存する
  • 文字列やデータに依存する
  • 別のオブジェクトに依存する

の順でテストがしづらくなる、という話です。このオブジェクト、もしかして数値にできないか? など振り返ってみるのはいいやり方かもしれません。

名前がカッコよければ多分大丈夫

すんなりフィットする名前がいきなり決まれば、きっと設計はうまくいっていると思います。というより、いい名前が思いつくことが稀とも言えて、リファクタするポイントの一つのマークになるかもです。

Formatterはおっしゃる通り怪しい名前で、このプログラムが大きくなったら責務超過になったりするような雰囲気があります。ダメとは言わないが要注意ぐらいの。

リファクタを恐れない

とはいえ、書いているうちにクラスを分割したり統合したりするのは正直よくあると思います。

ポイントとしては、外から見た振る舞いを崩さないようなテストを用意しておいて、そもそも壊れていることをすぐ気づけるようにすべきです。「外からのテスト」は統合テストとかE2Eテストとか、書いているものの粒度によりますが...。


最後に言い訳を思いっきりするとぼくはクラス設計、オブジェクト指向に関してはまとまって勉強をしたことがなく、経験で書いている面もあります...

メンターの皆さん、適宜突っ込んでください。私も勉強させていただきます。

@udzura
Copy link
Author

udzura commented Jun 17, 2020

言い訳をコメントすると、悪名高い Manager が存在していますので、これはアプリケーションの機能が膨らんだら分割していく前提で入れております。

@yoshikouki
Copy link

Managerクラスめっちゃ便利な名前!!
と思ったのですが、「便利な名前」だから巨大化したときに負債になる可能性があるとうことでしょうか・・・
「大きくて便利な名前」だとなんでも屋になってしまいますね😂

クラスがとても細かく切り出されていて、私の設計ではまだクラスが大きいんだということに気付けました
質問なのですが、1ファイルに対して1クラスを記述する形ですか?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment