ほとんどすべてのソフトウェアには、外部に公開したくない内部データ構造がいくつかあります(たとえば、APIを介して)。
1:1データベーステーブルを表すクラスがいくつかあるとしましょう-User
、UserGroup
、GroupPermission
など。
次に、APIで公開される外部クラスExternalUser
を作成し、ユーザーの詳細とユーザーグループの詳細を公開します。
ExternalUser
のプロパティを指定するには2つのオプションがあります。
プロパティのコピー --ExternalUser
には、プロパティのサブセットまたはUser
およびUserGroup
から派生したプロパティのコピーがあります
1.1。 ExternalUser
には、たとえば、username
、fullName
、userGroups
などをプロパティとして含めることができます。
1.2これらのプロパティはすべて、オブジェクトの作成時に入力され、内部User
およびUserGroups
からコピーされます
ラッピングオブジェクト-ExternalUser
にはUser
およびUserGroup
への参照があります。
2.1 ExternalUser
には、内部モデルへの参照を保持するプライベートuser
とuserGroup
があります。
2.2 getName
のようなメソッドは、内部のuser.getName
などに委任します。
トランザクションを処理している場合、データのリーク、メモリの使用、およびセッション管理の両方の長所と短所を確認できます。
パターン/標準、または一方のオプションがもう一方のオプションよりもはるかに優れている理由はありますか?
私があなたを正しく理解している場合、プロパティをコピーすることは、カプセル化を使用せずnot、単に個々のフィールドをExternalUser
のインスタンスに設定することを意味します、私は正しいですか?
プロパティをコピーすることにより、基本的にプログラムをより堅牢にすることを試みます。内部にカプセル化された洗練されたタイプを持たないExternalUser
などのPOJOクラスは、プログラムの実際の実装を、それを使用するものと切り離す非常に良い方法です。 APIを呼び出すユーザーは、おそらくExternalUser
のインスタンスを受け取り、いかなる種類の問題も発生しません。データは存在し、必要に応じて便利にシリアル化できます。
内部クラスのインスタンスをカプセル化することにより、ExternalUser
クラスは実装にはるかに依存するようになります。これは必ずしも悪いことではありません。User
およびUserGroup
のメソッドを変更すると、このロジックがExternalUser
または他の場所。ただし、この方法で行う場合は、すべての内部実装を非表示にするように注意する必要があります。 ExternalUser
はこれ専用のクラスである必要があるため、すべてのパブリックメソッドと、はい、プライベートメソッドもUser
またはUserGroup
インスタンスを返さないようにする必要があります。なぜプライベートメソッドも?リフレクションを介してプライベートメソッドにアクセスできるためです。
堅牢性を好むわけではありませんが、DRYの原則に従っています。これにより、プログラムがより柔軟になり、一般的に保守が容易になります。
私の個人的な好みは、インターフェースを単純で堅牢に保つことなので、ExternalUser
にはPOJOクラスを使用します。 DRYの原則に可能な限り従う場合は、呼び出し元にデータを返すまで、ExternalUser
の使用を避けてください。ExternalUser
は、 strictlyこの時点での外部クラスですが、これは小さなプロジェクトでは少々やり過ぎかもしれませんので、最終的には個人の好みに依存します。
2つのケースがあります
通常、追加のオブジェクトは必要ありません。どうして?出力をシリアル化する場合、通常は@Ignore
や@Expose
などのアノテーションを使用して、データをJSON/XMLに選択的にシリアル化できるためです。
次に、プロパティをExternalUser
などにコピーする必要があります。どうして?個人会員の内容を振り返って調べることはおそらく可能だろうから。
APIの場合は、どちらも行う必要はありません。
Apiのクライアントライブラリで使用するには、ExternalUserオブジェクトが必要なので、そのうちの1つが必要です。
外部ユーザーのフィールドのデータのみを含む文字列を生成するためにAPIが必要です。ただし、これを実現するためにExternalUserオブジェクトをシリアル化する必要はありません。
Userオブジェクトから必要なプロパティのみを含めるようにシリアライザーを構成するだけで済みます。