Javaにおけるプライベートクラスデータパターン:カプセル化によるデータ整合性の保護
別名
- データ隠蔽
- カプセル化
プライベートクラスデータデザインパターンの目的
Javaのプライベートクラスデータデザインパターンは、オブジェクトの内部状態へのアクセスを制限することに焦点を当て、メソッドアクセスを制御することでセキュリティを強化し、データ破損のリスクを軽減します。
実際の例を用いたプライベートクラスデータパターンの詳細な説明
実世界の例
プライベートクラスデータパターンの実世界の例えは、銀行が顧客の口座情報を保護する方法です。プライベートフィールドを持つクラスと同様に、銀行は口座残高、取引履歴、個人情報などの機密データを非公開にして、特定のメソッドを介してのみアクセスできるようにします。顧客は、ATMやオンラインバンキングポータルなどの明確に定義されたインターフェースを介して自分の口座とやり取りします。これらのインターフェースは、セキュリティと検証ルールを適用し、不正アクセスや変更を防止します。この制御されたアクセス機構は、プライベートクラスデータがソフトウェア設計でクラス属性へのアクセスを保護および管理する方法と同様に、データの整合性とセキュリティを確保します。
簡単な言葉で
プライベートクラスデータパターンは、データの状態を維持するクラスにデータを分離することにより、不変であるべきデータの操作を防ぎます。
Wikipediaによると
プライベートクラスデータは、クラス属性とその操作をカプセル化するために使用されるコンピュータプログラミングの設計パターンです。
Javaにおけるプライベートクラスデータパターンのプログラム例
家族の夕食のためにシチューを作っていると想像してください。あなたは、まだ準備をしている間に家族がシチューを味見するのを止めたいと思っています。もし彼らがそうすると、夕食には十分なシチューが残っていないかもしれません。
まず、`Stew`クラスがあり、そのデータはプライベートクラスデータによって保護されていないため、シチューの材料はクラスメソッドによって変更可能です。
@Slf4j
public class Stew {
private int numPotatoes;
private int numCarrots;
private int numMeat;
private int numPeppers;
public Stew(int numPotatoes, int numCarrots, int numMeat, int numPeppers) {
this.numPotatoes = numPotatoes;
this.numCarrots = numCarrots;
this.numMeat = numMeat;
this.numPeppers = numPeppers;
}
public void mix() {
LOGGER.info("Mixing the stew we find: {} potatoes, {} carrots, {} meat and {} peppers",
numPotatoes, numCarrots, numMeat, numPeppers);
}
public void taste() {
LOGGER.info("Tasting the stew");
if (numPotatoes > 0) {
numPotatoes--;
}
if (numCarrots > 0) {
numCarrots--;
}
if (numMeat > 0) {
numMeat--;
}
if (numPeppers > 0) {
numPeppers--;
}
}
}
次に、`ImmutableStew`クラスがあり、そのデータは`StewData`レコードによって保護されています。 `ImmutableStew`のメソッドは、`StewData`クラスのデータを操作できません。
public record StewData(int numPotatoes, int numCarrots, int numMeat, int numPeppers) {}
@Slf4j
public class ImmutableStew {
private final StewData data;
public ImmutableStew(int numPotatoes, int numCarrots, int numMeat, int numPeppers) {
data = new StewData(numPotatoes, numCarrots, numMeat, numPeppers);
}
public void mix() {
LOGGER
.info("Mixing the immutable stew we find: {} potatoes, {} carrots, {} meat and {} peppers",
data.getNumPotatoes(), data.getNumCarrots(), data.getNumMeat(), data.getNumPeppers());
}
}
それぞれのクラスのインスタンスを作成し、それらのメソッドを呼び出してみましょう。
public static void main(String[] args) {
// stew is mutable
var stew = new Stew(1, 2, 3, 4);
stew.mix();
stew.taste();
stew.mix();
// immutable stew protected with Private Class Data pattern
var immutableStew = new ImmutableStew(2, 4, 3, 6);
immutableStew.mix();
}
プログラム出力
08:00:08.210 [main] INFO com.iluwatar.privateclassdata.Stew -- Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers
08:00:08.212 [main] INFO com.iluwatar.privateclassdata.Stew -- Tasting the stew
08:00:08.212 [main] INFO com.iluwatar.privateclassdata.Stew -- Mixing the stew we find: 0 potatoes, 1 carrots, 2 meat and 3 peppers
08:00:08.213 [main] INFO com.iluwatar.privateclassdata.ImmutableStew -- Mixing the immutable stew we find: 2 potatoes, 4 carrots, 3 meat and 6 peppers
Javaでプライベートクラスデータパターンを使用する場合
プライベートクラスデータパターンを使用する場合
- オブジェクトの状態の整合性を保護したい場合。
- 意図しない変更を防ぐために、オブジェクトの内部データの可視性を制限する必要がある場合。
- 複数のクラスが、共通のデータを直接公開することなく、共有アクセスする必要がある場合。
Javaにおけるプライベートクラスデータパターンの実際の適用例
- プロパティがゲッターとセッターを介してアクセスされるJava Beans。
- 整合性とセキュリティを確保するために、内部状態がユーザーから隠されている多くのJavaライブラリ。
- 機密データを直接アクセスから保護する必要があるエンタープライズアプリケーション。
プライベートクラスデータパターンの利点と欠点
利点
- セキュリティの強化:データをカプセル化することにより、意図しないデータ破損のリスクを軽減します。
- メンテナンスの容易さ:データの内部表現を変更しても、外部コードには影響しません。
- 抽象化の向上:ユーザーは、データ管理の複雑さを気にすることなく、簡素化されたインターフェースと対話します。
欠点
- パフォーマンスのオーバーヘッド:追加のメソッド呼び出し(ゲッター/セッター)により、わずかなパフォーマンスのオーバーヘッドが発生する可能性があります。
- 複雑さ:データアクセスのための追加のメソッドレイヤーにより、クラス設計の複雑さが増す可能性があります。
関連するJavaデザインパターン
- プロキシ:どちらのパターンも基になるオブジェクトへのアクセスを制限しますが、プロキシはオブジェクト自体へのアクセスを制御し、プライベートクラスデータはデータへのアクセスを制御します。
- シングルトン:クラスにインスタンスが1つだけ存在することを保証し、グローバルなアクセスポイントを提供します。多くの場合、制御されたアクセスで共有データを管理するために使用されます。
- デコレータ:構造を変更することなく、オブジェクトに動作を追加します。プライベートクラスデータと組み合わせて、追加の状態を非公開で管理できます。