存在しない場合にgetで何かを作成するのは悪いコーディング習慣ですか?


17

だから私はgetAccountそれがそれを取得した場合、アカウントに識別子を返すようなものを持っているウェブサービスを持っている、そうでなければ例外をスローします。クライアントは、取得と同じ情報で例外がスローされた場合、常にアカウントを作成したいと思うでしょう。

クライアント用の便利なライブラリを作成しています。このライブラリは、内部ですべてのWebサービス呼び出しを処理するため、呼び出しを自分で行う方法を知る必要はありません。

私が疑問に思っているのはgetAccount(accountName)、アカウントが存在する場合にアカウントを取得するものを作成し、それを作成して情報を返さない場合、それは悪いことですか?例外を処理するためにクライアントに任せるか、単にgetOrCreateAccountのような名前を付ける必要がありますか?それは重要ですか?

get操作で何かを作成するのは悪い習慣ですか?


9
少なくとも、私はそれにgetOrCreateAccount似た名前を付けます。
テラスティン

4
遅延初期化のコンテキストで有効なようです。ただし、ライブラリでそのパターンを使用する必要があるかどうかによって異なります。
クリスC

1
私は動詞acquireが好きacquireAccountです。私が遭遇した主要なプロトコルには既存の意味はなく、それに適した命令的なリングがあります。「これらのいずれかを私のために獲得するためにあなたがしなければならないことは何でもしなさい。それを要求し、それを作り、それを偽造し、それを盗みなさい。
ダン・ロス

2
「クライアントは常にアカウントを作成したいでしょう」-それは非常に珍しいようです。ユーザーがユーザー名を誤って入力したためにアカウントを取得できない場合、名前を誤って入力したアカウントを作成したくないことは確かです。
gnasher729

javabeanの仕様によると、oracle.com / technetwork / articles / javaee / spec -136004.html getSomething()はゲッター用でありsetSomething()、セッター用です。芋より知的な何かをするもの、すなわち、他の何かに呼び出さなければなりませんfetchSomethingobtainSomethingcomputeSomething、またはdoSomethingElseなど
ccpizza

回答:


31

はい、それは重要です。私の意見では、作成の力があると文書化されていない手順で何かを作成することは、一般的に悪い習慣です。プロシージャに名前を付けるかgetOrCreate...、別のcreate...プロシージャを作成してから、本当に必要な場合はgetOrCreate...最初に試行しget...、失敗した場合は呼び出しcreate...てから呼び出しますget...

ライブラリのユーザーは、get...get操作が失敗した場合、おそらくプロシージャの作成を期待しないでしょう。テスト呼び出しがget...大量のデータを作成することを突然見つけた場合、彼らはおそらく驚くでしょう。そして、彼らはどのようにそれをきれいにしますか?get...失敗するとエラーが発生すると考えてコードを記述し、その方法で処理したい場合はどうなりますか?


おかげで、createは実際にgetが返すIDを返すのでget... create... get...、最初の2つだけを行う必要はありません。クライアントに、get作成することなく単に電話をかける機能が必要になるかどうかについて話します
マイク

6
@Mike:create名前に含まれているべきだと思います。何が起こっているかを100%明確にするためです。
FrustratedWithFormsDesigner

はい、私は私の元の考えはちょうどDO取得することだったので、私はそれをgetOrCreateの線に沿って何かを作ることに計画していたが、私はすぐに、それはまた、バックグラウンドで何かを作成していることが明らかにされていないことに気づき、同意する
マイク・

1
これは非常に遅いですがgetOrCreate、人気のあるWebフレームワークで優先順位があります: docs.djangoproject.com/en/1.10/ref/models/querysets/…–
tex

18

いいえ、それは「悪い習慣」ではありません。あなたと他の開発者が、あなたがそれをどのように動作させたいかに同意する限り、それは問題ありません。結局のところ、それはあなたが望むものであるアカウントを返すことになります。アカウントが「内部」で作成されることは、呼び出し元とは無関係です。


10
唯一の例外は、公開されているAPIの場合です。より大きなコミュニティは、GETがin等無能であることにすでに同意しています。つまり、同じアクションが毎回実行され、サーバーの状態を変更しない安全な方法です。これはREST Wikiにあります。それとは別に、もしAPIがあなた自身の小さな世界に存在するだけなら、あなたのグループによって受け入れられたものは何でもしてください。
jmort253

9
パブリックAPIでさえも、APIが何をすべきかという文脈の中意味をなす限り、私は同意しません。APIで複数のエントリを作成しても、1つのエントリでうまくいく場合はほとんど意味がありません。
GrandmasterB

記録のために、それは完全に内部のライブラリであり、私はそれを使用するチームにそれがどのように機能するかを伝える能力を持っています
マイク

1
@ jmort253:クライアントに見える副作用がない場合、サービスは無効です。サーバーは必要に応じて実行できます。
ケビンクライン14

1
@kevincline、私は私のクレジットカードに請求するという観点から考えていたと思います。サーバーがGETリクエストに基づいてカードに課金しても、実行するたびに「拒否」のような結果が得られる場合、それはGETの精神に反しているように感じます。とはいえ、私はあなたの主張を理解しています。サーバーはGETリクエストの数をカウントし、3つのクエリの後に私をロックアウトすることができます。これにより、アカウントの詳細を変更せずにレート制限されます。サーバーの状態は変更されないと言うとき、それは重要な違いだと思います。おそらく、私の代わりに、「サーバー上のクライアントの状態を」言うべき
jmort253

10

getAccount()常にアカウントを返すことができる場合、発信者の観点からは、アカウントは存在し、常に存在しています。getAccount()何も「作成」する必要はありません。アカウントは、デフォルトのアカウントと異なるまでどこにでも保存する必要はありません。


+1は一般的に、GetOrCreate間違ったセマンティックですが、「論理的に」それがphyiscally存在するかどうか存在する可能性があるオブジェクトを取得することは結構です。例として、可変アイテムのまばらな配列には、要素1,841,533に割り当てられたストレージがない場合がありますが、新しいオブジェクトを作成して格納し、参照を返すことにより、その要素を「取得」できます。
supercat 14

4

3つのメソッドを作成するのが最も理にかなっています:

getAccount->アカウントを取得するだけです。

createAccount->アカウントを作成します。

getAccountAndCreateIfNeeded->独自の命名を選択してください;)

分離の理由:取得と作成の簡単な方法があります。これは、両方のテスト可能な明確な方法です。getAccountの場合、アカウントが見つからないことも例外ではありません。したがって、falseまたはそのようなものを返すだけです。

その後、グループ化された関数でその戻り値を使用できます:getAccountAndCreateIfNeededはテスト可能になり、常にアカウントを返します。あなたが尋ねるものは何でも。

これら3つのメソッドはすべて明確であり、何を実行し、何を返すのかが明確です。チームと今すぐ契約を結ぶこともできますが、この種の例外は長期的にはひどいものです。明確にするだけで問題はありません。


また、Clean Codeから:「メソッドがその名前が示すとおりにできない場合、例外をスローします。」「GetOrCreateIfneeded」内にTry / Catchブロックがあり、失敗したGETをスローし、失敗したgetに対して返される例外タイプのThrow内に「createAccount」があります。
グラハム

4番目の方法を提案するかもしれません:getAccountIfExistsアカウントを取得するか、新しいアカウントを作成しないとアカウントが存在しないことを示します。getAccountこの方法自体は、アカウントが存在することを前提とし、ない場合に例外をスローする必要があります。
supercat 14

2

それは状況に依存します。

たとえば、それを使用して遅延ロード/インスタンス化を実行し、実際に必要になるまでデータのロードまたはインスタンスの作成を延期できます。これは、通常は必要ではないかもしれないリソースを節約するので賢明です(クラス/データが必要とされない場合、ロードされません)。

ただし、この特定のケースでは、存在しない場合に新しいアカウントを作成するgetAccountというメソッドを使用するのは良い習慣ではないと思います。ユーザーが特定のアカウントを識別するための資格情報を与えたがそのアカウントが見つからなかった場合、それはユーザーがまだ顧客ではないためアカウントを作成する必要があることを意味しますか、それとも資格情報の入力ミスを意味しますかそして、ユーザーは、入力したいものを入力したことを確認するように求められる必要がありますか?

アカウントを識別できなかった場合に新しいアカウントを作成するgetAccountメソッドがある場合は、この問題に選択肢はありません。アカウントの作成とアカウントの取得を別々の方法に分割すると、アカウントを取得しようとして失敗した場合の対処方法をより柔軟に決定できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.