【オブジェクト指向】クラス設計で、インスタンス変数にするか、戻り値にするか他
- 評価
- クリップ 1
- VIEW 1,207
処理概要
- APIを実行してデータを取得し、2つの異なる格納先にInsertします。(DBと別のストレージ、具体的にはAzureのTableStorage。ストレージはバックアップ用)
- APIは複数回実行するため、「API実行→DB用エンティティ作成・リストに追加→ストレージ用エンティティ作成・リストに追加」の処理をすべて実行した後、最後に2つのリスト内のエンティティをループしてInsertします。(コネクションを1回にするため)
クラス
作成するクラスは以下を想定します。(下記の質問で一部まとめたりしています)
- 呼び出し元クラス(コントローラ)
- API実行クラス
- DBエンティティ作成クラス
- ストレージエンティティ作成クラス
- DBInsertクラス
- ストレージInsertクラス
質問内容・シーケンス図
試行錯誤して、いくつかシーケンス図を作ってみましたが、何がベストプラクティスかがわかりません。
- リストを保持すべきクラスはどこでしょうか?(コントローラか、エンティティ作成クラスか、Insertクラスか)
- API実行、DBエンティティ生成、ストレージエンティティ生成の呼び出し元はどこが良いのでしょう?(呼び出しは依存させた方がよいのか、させない方がよいのか、実行順序が重要な場合は依存させた方が良い・・・?)
- 各エンティティクラスのinデータはJSONデータがよいのでしょうか?(同じようなJSONデータの取り出し処理をするのは嫌だなぁという感覚です)
- エンティティ生成と登録処理は、同じクラスがよいのでしょうか?(凝集性的には同じクラスが良いと思いますが、単一責任原則的には別の方が良いのかなと。また、エンティティ作成処理は20~30行の処理なので、行数的にも分けた方が良いのかなと)
その他
これが絶対に正解!というものはないかもしれませんが、一般的に良いとされる設計がどのようなものか、知りたい次第でございます。煩雑で申し訳ございませんが、よろしくお願いいたします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
メッセージの設計がまだ曖昧だからでしょう。
メッセージの内容が具体的になると、継承させた方が良いとか、クラスの構成もまた変わってくると思います。
クラス設計の場合、ロジック部分よりもデータに主眼を置いて設計する方が良いと思いますよ。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
とりあえず↓サイトを参考にどうぞ
インフラストラクチャの永続レイヤーの設計
DBエンティティ作成クラス/ストレージエンティティ作成クラスの戻り値のエンティティがどういうものを想定しているのかわからないのですが、
以下は作成クラスの処理内容がJSONからDTOへのマッピング、という前提で話をしてます
API実行、DBエンティティ生成、ストレージエンティティ生成の呼び出し元はどこが良いのでしょう?(呼び出しは依存させた方がよいのか、させない方がよいのか、実行順序が重要な場合は依存させた方が良い・・・?)
まず処理の目的はなんなのか分析してみたらどうでしょうか
例えばユーザー(コントローラーを呼び出す側)のやりたいことが、データを取得して後に利用するため保持しておきたいだけならば
“API”を用いて取得することや、DBへの登録/ストレージへのバックアップという(どこにどうやって保存するなどの)詳細は関心事ではない
というような分析です
このような分析なら、データ取得処理の抽象化/永続化処理の抽象化をしてあげるとよいでしょう
C#の場合、インターフェースを使うことになるでしょう
例えば、データの永続化処理は別namespaceに分けて、それにはインターフェースを通してアクセスする形式にするなどです
テストのモックも作りやすくなりそうですね
エンティティ生成と登録処理は、同じクラスがよいのでしょうか?(凝集性的には同じクラスが良いと思いますが、単一責任原則的には別の方が良いのかなと。また、エンティティ作成処理は20~30行の処理なので、行数的にも分けた方が良いのかなと)
一般に、単一責任原則を満たすと凝縮度は高くなると言えますから、ちょっと混乱している印象を受けました
以下、単一責任原則の参考にどうぞ
https://code.tutsplus.com/ja/tutorials/solid-part-1-the-single-responsibility-principle--net-36074
単一責任原則的には、エンティティ登録処理を呼び出す側が単一であれば一クラスにまとめてよいと思います
つまり、取得されるJSONの形式が一部異なることがあるとか、JSON以外の形式のデータを取得する場合があるとかで、登録処理にくっついた生成処理の中に分岐を作るような可能性がなければありです
ただ、僕個人としてはたぶんマッピング専用クラスを作っちゃいますね
データの登録と、JSONからDTOへの変換、を密に結合する必要は大抵の場合ないと思います
マッピングクラスは特別な事情がなければstaticなものにします
できれば自動生成する仕組みを用意してあげるとよいでしょう
各エンティティクラスのinデータはJSONデータがよいのでしょうか?(同じようなJSONデータの取り出し処理をするのは嫌だなぁという感覚です)
括弧内の意味がちょっとよくわからなかったのですが、各エンティティクラスとは、登録するクラスのことですか?
その場合、↑で何度か述べていますが、その登録クラスのInputになるデータの形式が将来的にJSON以外もありえるか検討しましょう
僕個人としては、JSONよりもDTOの方が取り回しが良いかと思います
また、単体テストの難易度がどうなるか、という観点で考えてみるとよいでしょう
例えば、ローカル環境で実際にテーブルアクセスして登録できたか確かめるテストを作成するとき、InputとしてJSONを作成するのは簡単ですか?また、変更があった時、テストのメンテはしやすいでしょうか?
リストを保持すべきクラスはどこでしょうか?(コントローラか、エンティティ作成クラスか、Insertクラスか)
コネクション/トランザクションの管理をどう行っているのか不明なのであまりはっきりとしたことは言えませんが、
ループでリストを作って、そのリストを別のループで回してInsertするよりは、一つのループ内で済ませてしまうほうが良いかと思います
フレームワークの制約などでそのようにできない場合は、
エンティティ作成クラスは単純なMapperであった方がいいと思うので、コントローラか各Insertクラスに持たせてしまうとよいでしょうね
コントローラに持たせる場合、普通のローカル変数で、データ取得処理で取得したものをMapperで変換しながらどんどん追加していき、最後にInsertクラスで処理する感じになりますかね
あるいは、各InsertクラスにQueueの性質を持たせることも考えられます
単一のDTOを引数にとるputメソッド的なものを持たせて、Insertクラス内のプロパティにどんどん追加していき、最後にInsertメソッドを実行するようなイメージです
アーキテクチャ設計(MVCやクリーンアーキテクチャなど)がどうなっているかでもまた変わってきますが、とりあえず以上です
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2019/05/07 16:35
追加で質問ですが、「メッセージ」とは何を指していますか・・・?
2019/05/07 16:45
シーケンス図に於いては一般的なものです。
http://www.itsenka.com/contents/development/uml/sequence.html
2019/05/07 16:58
「メッセージ設計が曖昧」というのは、「jsonデータ」のデータの内容を把握できていないという意味でしょうか?
上記の意味合いでしたら、jsonデータの内容は明確にはなっています。(一応動くものはできていて、リファクタリングしているところです)
(たぶんクラス設計の知識が不足しすぎているため、そう認識してしまったかと思います、すみません)
jsonデータが明確になった後の次の工程は何でしょうか?
2019/05/07 17:20
画面での入力なのかDBなのかなどを検討しつつ画面遷移も合わせて検討することになります。
メッセージの形式をどうするかはクラス間の連携の方式に依存しますので、副次的なものです。
ここで言いたいのは、メッセージをどのように持ち回るかを考えると良いだろうという事です。
どのタイミングでDBに格納する必要があるかとか、セッション情報に保持しておくべき情報であるとか。
2019/05/07 17:24 編集
2019/05/07 17:59
> どのタイミングでDBに格納する必要があるかとか、セッション情報に保持しておくべき情報であるとか。
なるほど、「ロジック部分よりもデータに主眼を置いて設計する」の意味が分かりました。
が、処理をどのクラスから呼び出すか、データをどう持ちまわるかの選択肢はいくつもあると思いますが、どのような基準で選択すればよいのでしょうか?この疑問が今回の質問の主となる部分です。
2019/05/07 18:19