0
12
テーマ、知りたいこと
設計は何に着目すればいいのでしょうか。
オブジェクト指向などの本も読んでみましたがよくわからないです。
vendingMachine (自動販売機) を例にとると
① 仕様に着目 (動詞 メソッド風?)
(1) storeJuice ジュースを保管する
(2) coolJuice ジュースを冷やす
(3) checkPayment 支払いを確認する
(4) outputJuice ジュースを排出する
② 場所に着目 (名詞 クラス風?)
(1) juiceStore ジュースの保管場所
(2) cooler ジュースの冷却器
(3) moneyBox 金銭管理箱
(4) vent ジュースの排出口
③ 目的物に着目 (名詞 データが主役のクラス風?)
(1) storedJuice 保管されたジュース
(2) coolingJuice 冷やされたジュース
(3) boughtJuice 支払いが確認されたジュース
(4) outedJuice 排出されたジュース
本やネットでクラスが名詞でメソッドが動詞と学びましたが
どうにでも書けてしまえませんか?
それとも何か基準やルールでもあるのでしょうか。
着目するところやコツがあれば教えていただきたいです。
追記1
"どうにでも" というのは少々乱暴な言い方でした。すみません。
言いたいことは、自動販売機の例でいうところの、仕様に着目しても場所に着目しても目的物に着目しても分かりやすさと保守性があれば、どのような設計を選んでも構わないのかということです。
追記2
着目したテーマ(仕様/場所/目的物 etc.)によって、同じ動きをするプログラミングの関数名が動詞句(メソッド)になることも名詞句(クラス)になることもあるということなのでしょうか。(例えば、juiceStoreクラスにcountJuiceメソッドがあったとして、構成によってはjuiceStoreコンポーネントのjuiceCounterクラスにもなる?)
追記3
#6を読んで疑問に思ったのですが、クラスは 「AはBをする」に縛られるのでしょうか。「AがBになる」で作らないほうがいいのでしょうか。例えば、ぬるいジュースから冷たいジュースになるということで normalTemperatureJuice クラスと coolingJuice クラスを作るという設計はNGですか。
追記4
0. 状況整理
悩む方向が間違っているのかもわかりませんが、悩んでいることをまとめ直しました。
(1) シナリオの着眼点
(2) クラス(名詞句)/メソッド(動詞句)の使い分け
(3) 共通クラス/メソッドの置き場とネーミング
※青は名詞句 黄緑は動詞句。
1. 設計の大枠
vendingMachineの大枠を実体面(ハードウェア)から考えた。
さらにvendingMachineの大枠を動作面(SVO)から考え直した。
疑問①-1: SVOからのアプローチの語法
「vendingMachineのオーナーがjuiceを追加した。」という動作面(SVO)からのアプローチでは、juiceクラスがjuiceSettingのようなネーミングになるのか。storeManagement とstoreManager ではどちらになるのか。一般的なルールはあるのか(そもそも、クラスの命名自体もわかっていない。)
疑問①-2: 着眼点の違うシナリオの混在 1/2 (粒度の等しいクラス)
自販機の実体面からアプローチしたクラスとオーナーの動作面からアプローチしたクラスの混在など、着眼点の違いがあるクラスの併存はよくあることなのか、避けていることなのか、例外的に事情があれば許容されるのか。(実体面に着目しても動作面に着目しても、どのようにも書けるのではないかという疑問はこのようなことに端を発している。)シナリオに制約や経験則的に破綻しやすいケースはあるのか。
2. 汎用性があるクラスへの再編
juiceクラスは汎用性が無いため、itemクラスに再編した。
ここではoden(おでん)はfoodのほうが良いのではないかという再々編の余地を残しているがこの設計で大きな影響はない。
疑問②-1: 着眼点の違うシナリオの混在 2/2 (クラスとメソッド)
自販機の実体面から考えられたクラス内にオーナーの動作面から考えられたメソッドという、以下のような構成もありえるのか。
処理過程も見方によっては目的となり、また逆もあり、名詞句なのか動詞句なのかの違いだけで内容が同じ関数に関してクラスとメソッドには大きな隔たりが無いように感じているが、どのようにクラスとメソッドの住み分けを進めればいいのか。
一旦すべての構成をドメイン/クラスとった樹形図のような名前空間に落とし込み、そこからさらに”名前空間をつくる程でもない処理”をメソッドとして扱っても設計できそうだが、メソッドはそのように捉えるべきではないのか。
3. 共通するメソッドの扱い 1
各クラスに以下のメソッドが付加された。
処理が共通するおまけ飴メソッドのaddRedCandyとaddBlueCandyを一つのaddCandyメソッドにまとめitemクラス配下とした。
疑問③-1: 関連度/粒度/抽象度
addCandyメソッドはjuiceクラスとtoyクラスで使われodenクラスには使われないが、配置する場所はitemクラス下で良いのか。それともjuice/oden/toy の粒度や抽象度に合わせてcandyクラスやadditionクラスを作り管理すべきなのか。
疑問③-2: メソッドの拡張性
addCandyメソッドにredやblueといった名詞句のタグ付けは可能か。(メソッド(動詞句) = 構成の行き止まりのようなイメージがあるのですがそんなことは無いですか。)addCandyメソッドに拡張性がないのであれば、candyクラスにしてしまうべきか。
疑問③-3: 冗長性
構成を厳密にしていくとitem/shared/addition/candy/redクラスを拾うことになるが名前空間や関数名は長くなっても構わないのか。引数は4つまでが良いと何かの本で読んだことがあったが、名前空間も読みやすさなどのルールがあるのか。
4. クラスの拡張
additionクラスをsharedクラスに拡張した。
banUpsidedown(天地無用)メソッドもoden以外にも使えそうな抽象性のあるメソッドなのでadditionクラスをsharedクラスとしてこれに移動させた。
疑問④-1: カプセル化と汎用性
オブジェクト指向(カプセル化)と汎用性のあるメソッドに親和性はあるのか。
汎用性のあるメソッド作るほど、元のクラスの中身が減っていくわけで、そうなると行程がいくつもあり肥大化したクラスを除いて、カプセル化を目指さないほうが無難なのではないか。
疑問④-2: 汎用性のあるメソッドのネーミングと名前空間 1/2
共用になりそうなしかし共用になっていないメソッドの配置とネーミングが悩ましいがどうすべきか。shared? option? 一度しか使わないようなメソッドもクラスやメソッドの粒度や抽象度を揃えたとき(シーケンスのレベルや位置が同じとき)共用クラスの中に入るなら、入れるべきなのか。
5. 共通するメソッドの扱い 2
itemが自販機にあるのか無いのかを返すexistItemメソッドを追加した。
itemに関わることなのでitemクラスにあるが、使われるのは自販機の売り切れボタンである。
(existItem? isExists? itemExists? 語法が正しいのか分かりません。)
疑問⑤-1: 再利用性のあるメソッドの置き場
itemクラス内のbanUpsidedownメソッドがdisplayクラスでも再利用性があるという場合はメソッドの場所をitemクラスとdisplayクラスの共用クラスに変更したほうが良いのか。
疑問⑤-2: 分類場所優先か利用場所優先か
existItemメソッドはitemクラス内で一度も使われない。しかし、itemクラスに分類されるメソッドである。だがdisplayクラスで呼び出されるという場合、existItemメソッドはitemクラス(分類場所)内に置いておいていいのかdisplayクラス(利用場所)へ移動させたほうがいいのか。
回答24件
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。