著者のホームページ:デザイナー Xiao Zheng
著者について: JAVA テクノロジ、システム カスタマイズ、リモート ガイダンスに重点を置いた 3 年間の JAVA フルスタック開発経験、エンタープライズ デジタル トランスフォーメーションに注力、CSDN ブログ エキスパート、Blue Bridge クラウド コース認定インストラクター。
この記事では、Java デザイン パターンのプロトタイプ パターンについて説明し、サンプル コードを示します。プロトタイプ パターンの主な目的は、明示的なインスタンス化プロセスに依存せずに、既存のオブジェクトをコピーまたはクローンして新しいオブジェクトを作成することです。
目次
1. オブジェクトのクローン作成とは何ですか?
プロトタイプのパターンを学ぶ前に、まずオブジェクトの複製の概念を理解する必要があります。
Java では、オブジェクトのクローン作成とは、既存のオブジェクトのコピーを作成することを意味します\color{red}{オブジェクトのクローン作成とは、既存のオブジェクトのコピーを作成することを意味します}オブジェクトのクローン作成とは、既存のオブジェクトのコピーを作成することを指します。オブジェクトのクローン作成は通常、元のオブジェクトに影響を与えずに同じ状態の新しいオブジェクトを作成するために使用されます。
Cloneable
Java でのオブジェクトの複製は、インターフェースを実装し、メソッドをオーバーライドすることによって実現できますclone()
。
クローン作成を使用する場合、 clone() メソッドを使用してオブジェクトのコピーを作成できます。このメソッドは、元のオブジェクトと同じプロパティ値を持つ新しいオブジェクトを返します。
Java のclone()
メソッドは浅いコピーを実行します。これは、複製されたオブジェクトと元のオブジェクトが同じ参照型フィールドを共有することを意味します。深いコピー、つまり複製されたオブジェクトとそのすべての参照型フィールドのコピーを実装する必要がある場合は、の場合は、 メソッドで行う必要がありますclone()
。それに応じて処理してください。
2. ディープ コピーとシャロー コピーとは何か、またその違いについて話しましょう。
Java では、オブジェクトのコピーは浅いコピーと深いコピーの 2 つの方法に分けることができます\color{red}{オブジェクトのコピーは浅いコピーと深いコピーの 2 つの方法に分けることができます}オブジェクトのコピーには、浅いコピーと深いコピーの 2 つの方法があり、その違いは、オブジェクトをコピーする際に元のオブジェクトのコピーを作成するかどうか、および参照型フィールドの処理方法にあります。
2.1 ディープコピー
ディープコピーとは、参照型フィールドを含め、元のオブジェクトとまったく同じフィールド値を持つ新しいオブジェクトを作成することを指します。ディープ コピーでは、オブジェクトの基本型フィールドがコピーされるだけでなく、参照型フィールドのコピーを保存するための新しいオブジェクトも作成されます。これは、コピーされたオブジェクトの参照タイプ フィールドを変更しても、元のオブジェクトの参照タイプ フィールドは異なるオブジェクトを参照するため影響を与えないことを意味します。
2.2 浅いコピー
浅いコピーとは、フィールド値が元のオブジェクトとまったく同じである新しいオブジェクトを作成することを意味しますが、参照型フィールドの場合は同じ参照を共有します。つまり、浅いコピーではオブジェクト内の基本タイプのフィールドのみがコピーされ、参照タイプのフィールドの場合は、新しいオブジェクトを作成せずに参照のみがコピーされます。
浅いコピーでは、コピーされたオブジェクトの参照型フィールドを変更すると、元のオブジェクトの参照型フィールドに影響します。これは、元のオブジェクトとコピーされたオブジェクトが同じ参照を共有し、同じメモリ アドレスを指しているためです。
セクション 2.3
ディープ コピーを実装するにはさまざまな方法がありますが、より一般的に使用される方法には次のものがあります。3時。
Serializable
インターフェイスを実装することにより、オブジェクトのシリアル化と逆シリアル化を使用してディープ コピーが実装されます。Cloneable
インターフェイスとオーバーライドされたメソッドを使用してclone()
、ディープ コピーを実装します。- このメソッドでは、コピー オブジェクトの基本型フィールドを
clone()
呼び出すことに加えて、参照型フィールドに対して別のディープ コピー プロセスも必要です。super.clone()
要約すると、浅いコピーはオブジェクトの基本型フィールドと参照型フィールドへの参照のみをコピーしますが、深いコピーはオブジェクトの基本型フィールドと参照型フィールドのコピーをコピーします。
したがって、オブジェクトの独立性を維持し、元のオブジェクトの変更を避ける必要がある場合には、ディープ コピーを使用する方が適切な選択となります。
3. Javaオブジェクトコピーのパフォーマンス問題を解決する方法
Java では、特に大きなオブジェクトや複雑なオブジェクト グラフを扱う場合、オブジェクトのコピーでパフォーマンスの問題が発生する可能性があります。以下に、Java オブジェクトのコピーのパフォーマンスの問題を解決し、学生に参考となるいくつかの方法を示します。
-
プロトタイプ パターンを使用します。明示的なインスタンス化プロセスに依存せずに、既存のオブジェクトをコピーまたはクローンして新しいオブジェクトを作成します。これにより、新しいオブジェクトを直接作成するオーバーヘッドが回避されます。プロトタイプ パターンは、インターフェイスを実装し、メソッドをオーバーライドすることで実現できます
Cloneable
。clone()
-
浅いコピーを使用する: オブジェクトの基本タイプのフィールドをコピーするだけでよく、参照タイプのフィールドを共有できる場合は、浅いコピーの方が効率的です。浅いコピーにはフィールドのコピーのみが含まれるため、浅いコピーよりも高速です。深いコピー。
-
コンストラクターを使用する: コンストラクターを手動で作成して、元のオブジェクトのプロパティに基づいて新しいオブジェクトを作成します。これにより、
clone()
メソッドの呼び出しやCloneable
インターフェイスの実装のオーバーヘッドを回避できます。 -
シリアル化と逆シリアル化の使用: Java オブジェクトのシリアル化および逆シリアル化メカニズムを使用して、ディープ コピーを実現できます。オブジェクトをバイト ストリームにシリアル化し、それから新しいオブジェクトに逆シリアル化することで、オブジェクトとそのすべての参照フィールドを作成できます。独立したコピーですが、シリアル化と逆シリアル化によって一定のパフォーマンスのオーバーヘッドも生じます。
-
サードパーティ ライブラリを使用する: 一部のサードパーティ ライブラリは、より効率的なオブジェクト コピーの実装を提供します。たとえば、
Apache Commons
このライブラリはSerializationUtils.clone()
、オブジェクトのディープ コピーを迅速に実装するためのメソッドを提供します。 -
オブジェクト プールを使用する: オブジェクトを頻繁にコピーする必要がある場合は、オブジェクト プールの使用を検討してください。オブジェクト プールは、オブジェクトの頻繁な作成と破棄を避けるために、初期段階でオブジェクトのセットを作成し、必要に応じてプールからオブジェクトを取得して返します。 。
-
リファクタリングを検討する: パフォーマンスの問題はオブジェクト自体の設計に起因する場合があり、場合によっては、オブジェクトの構造を最適化するか、不要なフィールドを削減することでパフォーマンスを改善できる場合があります。
4. プロトタイプパターンとは何かを学ぶ
プロトタイプ パターンは創造的なデザイン パターンです\color{red}{プロトタイプ パターンは創造的なデザイン パターン}プロトタイプ パターンは、明示的なインスタンス化プロセスに依存せずに、既存のオブジェクトをコピーまたは複製することによって新しいオブジェクトを作成することを主な目的とする創造的なデザイン パターンです。
プロトタイプ パターンは、既存のオブジェクトの状態をコピーすることで新しいオブジェクトを作成し、新しいオブジェクトを直接作成するオーバーヘッドを回避します。プロトタイプ パターンは、インターフェイスを実装しメソッドをオーバーライドすることで実装できCloneable
ますclone()
。
プロトタイプパターンでは、コピーされたオブジェクトであるプロトタイプオブジェクトをプロトタイプと呼ぶことができます。clone メソッドはプロトタイプ パターンの中核部分であり、プロトタイプ オブジェクトのコピー方法を定義します。clone メソッドを使用すると、プロトタイプ オブジェクトと同じ状態の新しいオブジェクトを作成できます。
プロトタイプ パターンの主な利点は、実行時にオブジェクトを動的に作成できることです\color{red}{プロトタイプ パターンの主な利点は、オブジェクトを実行時に動的に作成できることです}プロトタイプ パターンの主な利点は、実行時にオブジェクトを動的に作成できるため、明示的なインスタンス化プロセスが回避され、オブジェクト作成の効率が向上すること。また、さまざまなニーズに合わせてクローン オブジェクトを変更することで、同じ状態のオブジェクトを作成する簡単な方法も提供します。さらに、プロトタイプ パターンは、オブジェクトの作成の詳細を非表示にして、クライアント コードを特定のクラスから切り離すこともできます。
ただし、プロトタイプ モードを使用する場合は、注意する必要がある問題がいくつかあります。まず、クローン オブジェクトには他のオブジェクトへの参照が含まれている可能性があり、オブジェクト グラフの重複につながる可能性があるため、特別な注意を払って扱う必要があります。第 2 に、クローン作成プロセスはオブジェクトを直接作成するよりも複雑になる可能性があり、クローン作成メソッドの合理的な実装が必要です。
プロトタイプ パターンは、実行時に同じ状態の新しいオブジェクトを動的に作成できる、オブジェクトを作成するためのシンプルかつ効率的な方法を提供します。同様のオブジェクトを作成する必要がある場合や、オブジェクト作成の詳細を非表示にする必要がある場合に非常に役立ちます。
5. プロトタイプモードの開始
以下はプロトタイプモードを使用した Java コード例ですので、ローカル実行にコピーしてください。
// 原型接口
interface Prototype extends Cloneable {
Prototype clone();
}
// 具体原型类
class ConcretePrototype implements Prototype {
private String name;
public ConcretePrototype(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public Prototype clone() {
try {
return (Prototype) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
ConcretePrototype prototype = new ConcretePrototype("Prototype 1");
System.out.println("Original object: " + prototype.getName());
ConcretePrototype clonedObject = (ConcretePrototype) prototype.clone();
System.out.println("Cloned object: " + clonedObject.getName());
clonedObject.setName("Prototype 2");
System.out.println("Modified cloned object: " + clonedObject.getName());
}
}
上の例では、独自のオブジェクトをコピーするメソッドをPrototype
含むプロトタイプ インターフェイス を定義しました。clone()
次に、具体的なプロトタイプ クラス を作成しConcretePrototype
、Prototype
インターフェイスを実装し、clone()
メソッドをオーバーライドしました。
クライアント コードでは、まずプロトタイプ オブジェクトを作成しprototype
、次にclone()
クローン オブジェクトを取得するメソッドを呼び出してプロトタイプ オブジェクトをコピーしますclonedObject
。
クローン オブジェクトのプロパティを変更することで、クローン オブジェクトとプロトタイプ オブジェクトが互いに独立しており、相互に影響を及ぼさないことを確認できます。
6. プロトタイプモードの適用シナリオ
試作パターンは通常以下の3・3になります。タイプ3の開発シナリオで使用されますので、簡単に理解してください。
- オブジェクトの作成には、データベース操作やネットワーク要求などの時間のかかる操作が含まれるため、コストが比較的高くなります。
- 作成するオブジェクトには既存のオブジェクトと同様のプロパティがあり、一部のプロパティのみを変更する必要があります。
- オブジェクトの作成の詳細を非表示にし、クライアント コードを具象クラスから分離する必要があります。
もちろん、プロトタイプ モードの使用が必要なアプリケーション シナリオもいくつかあります。
- 複雑なオブジェクトの作成: 複雑なオブジェクトの作成プロセスが退屈または時間がかかる場合は、プロトタイプ パターンを使用して既存のオブジェクトをコピーし、繰り返し作成することを避けることができます。
- プロトタイプ レジストリ: プロトタイプ パターンを使用すると、オブジェクトのコレクションを作成し、必要に応じてコレクションから既存のオブジェクトをコピーして、オブジェクトの作成効率を向上させることができます。
- ファクトリ メソッド パターンの代替: プロトタイプ パターンは、ファクトリ メソッド パターンの代替として使用できます。作成する必要があるオブジェクトが同じ基本クラスまたはインターフェイスを持ち、一部のプロパティのみを変更する必要がある場合、プロトタイプ パターンは、パターンはファクトリ メソッド パターンよりも柔軟です。
つまり、プロトタイプモードは、作成コストが高いオブジェクト、作成プロセスが複雑なオブジェクト、または作成内容を隠蔽する必要があるオブジェクトに適しており、既存のオブジェクトをクローンして新しいオブジェクトを作成することで、オブジェクト作成の効率を向上させることができ、さまざまな要求にも柔軟に対応できます。ニーズに応えます。
7. プロトタイプモードのインタビューの質問
1. プロトタイプモードとは何ですか? \color{red}{1. プロトタイプ モードとは何ですか? }1. プロトタイプモードとは何ですか?
プロトタイプ パターンは、明示的なインスタンス化プロセスに依存せずに、既存のオブジェクトをコピーまたは複製することによって新しいオブジェクトを作成する創造的なデザイン パターンです。
2. プロトタイプモードを実装するにはどうすればよいですか? \color{red}{2. プロトタイプ モードを実装するにはどうすればよいですか? }2. プロトタイプモードを実装するにはどうすればよいですか?
Cloneable
Java では、インターフェイスを実装しメソッドをオーバーライドすることでプロトタイプ パターンを実装できますclone()
。clone()
メソッドは、既存のオブジェクトの状態をコピーし、プロトタイプ オブジェクトと同じ状態の新しいオブジェクトを作成できます。
3. クローン法と構築法の違いは何ですか? \color{red}{3. クローン法と構築法の違いは何ですか? }3. クローン法と構築法の違いは何ですか?
clone メソッドは既存のオブジェクトに基づいて新しいオブジェクトを作成しますが、コンストラクター メソッドはクラスをインスタンス化して新しいオブジェクトを作成します。clone メソッドは既存のオブジェクトの状態をコピーしますが、コンストラクター メソッドは新しいオブジェクトの状態を手動で設定する必要があります。
4. プロトタイプモードの利点は何ですか? \color{red}{4. プロトタイプ モードの利点は何ですか? }4. プロトタイプモードの利点は何ですか?
プロトタイプ モードでは、実行時にオブジェクトを動的に作成できるため、明示的なインスタンス化プロセスが回避され、オブジェクト作成の効率が向上します。また、同じ状態のオブジェクトを作成する簡単な方法も提供し、オブジェクト作成の詳細を非表示にして、クライアント コードを具体的なクラスから切り離します。
5. プロトタイプ モードに適用できるシナリオは何ですか? \color{red}{5. プロトタイプ モードに適用できるシナリオは何ですか? }5. プロトタイプ モードに適用できるシナリオは何ですか?
プロトタイプ パターンは、作成に費用がかかる、複雑な作成プロセスがある、または作成の詳細を隠す必要があるオブジェクトに適しています。一般的な使用例には、複雑なオブジェクト、プロトタイプ レジストリの作成、ファクトリ メソッド パターンの置き換えなどがあります。
6. プロトタイプモデルの制限は何ですか? \color{red}{6. プロトタイプ モードの制限は何ですか? }6. プロトタイプモデルの制限は何ですか?
プロトタイプ パターンを使用する場合は、複製されたオブジェクトに他のオブジェクトへの参照が含まれる可能性があることに注意する必要があります。これにより、オブジェクト グラフが重複する可能性があり、特別な注意が必要になります。クローン作成プロセスは、オブジェクトを直接作成するよりも複雑になる可能性があり、clone メソッドの合理的な実装が必要です。
8. 記事の最後に特典あり
ファンの皆様の熱いご支援に報いるため、ブロガーさんは出版社の活動に参加する資格を取得し、清華大学出版局と協力してファンの皆様に書籍をお送りすることになりました!
ファンに贈る第 1 号は、95 万人の Java プログラマーが選んだ Java 入門書の定番『Java from Beginner to Master (7th Edition)』で、書籍の紹介は次のとおりです。
本書は、Java言語を使ってプログラム開発を行うために必要な知識を、初心者の視点から、わかりやすい言語と多彩なサンプルを通して詳しく解説しています。本書に記載されているすべての知識を具体的な例とともに解説し、関連するプログラム コードには詳細なコメントが付けられているため、Java プログラム開発の本質を理解しやすく、開発スキルを迅速に向上させることができます。
書籍購入リンク: JD.com、Dangdang.com。
アクティビティの報酬: 「初心者からマスターまでの Java (第 7 版)」 \color{red}{"初心者からマスターまでの Java (第 7 版)"}『Java from Beginner to Master (第7版)』は送料無料です。
参加方法:このブログに「いいね!」+「お気に入り」+コメントして参加します\color{red}{「このブログにいいね+お気に入り+コメント」して参加}のように+集める+参加するには、このブログにコメントしてください。
抽選時期: 2023 年 9 月 12 日。
通知方法: CSDN プライベート メッセージ。