5.プロトタイププロトタイプモード

プロトタイプモードは、頻繁に呼び出される非常に類似したオブジェクトで使用され、オブジェクトのクローンを作成して変更されたプロパティを設定し、消費するリソースを減らします。

プロトタイプモードは主にオブジェクトの複製に使用され、そのコアはクラス図のプロトタイプクラスPrototypeです。プロトタイプクラスは、次の2つの条件を満たす必要があります。

クローン可能インターフェースを実装します。Java言語にはCloneableインターフェイスがあります。このインターフェイスには、実行時にこのインターフェイスを実装するクラスでcloneメソッドを安全に使用できることを仮想マシンに通知する機能が1つだけあります。Java仮想マシンでは、このインターフェイスを実装するクラスのみをコピーできます。コピーできない場合、実行時にCloneNotSupportedExceptionがスローされます。

  1. Objectクラスのcloneメソッドをオーバーライドします。Javaでは、すべてのクラスの親クラスはObjectクラスです。Objectクラスにはオブジェクトのコピーを返すために使用されるcloneメソッドがありますが、そのスコープは保護されており、通常のクラスでは呼び出すことができません。したがって、Prototypeクラスはクローンを作成する必要があります。メソッドのスコープがパブリックタイプに変更されます。
  2.  プロトタイプモードは比較的単純なモードであり、非常に理解しやすいモードです。プロトタイプモードは、インターフェイスを実装し、メソッドを書き直すことで完了します。実際のアプリケーションでは、プロトタイプモードが単独で表示されることはめったにありません。多くの場合、他のモードと混合され、彼のプロトタイプクラスPrototypeはしばしば抽象クラスに置き換えられます。

クラス図

コード例

package designpatterns.prototype;
 
//原型
interface Prototype {
    void setSize(int x);
    void printSize();
 }
 
// 一个具体类
class A implements Prototype, Cloneable {
    private int size;
 
    public A(int x) {
        this.size = x;
    }
 
    @Override
    public void setSize(int x) {
        this.size = x;
    }
 
    @Override
    public void printSize() {
        System.out.println("Size: " + size);
    }
 
    @Override
    public A clone() throws CloneNotSupportedException {
        return (A) super.clone();
    }
}
 
//需要很多类似的对象进行测试
public class PrototypeTest {
    public static void main(String args[]) throws CloneNotSupportedException {
        A a = new A(1);
 
        for (int i = 2; i < 10; i++) {
            Prototype temp = a.clone();
            temp.setSize(i);
            temp.printSize();
        }
    }
}

 

プロトタイプモードの利点と適用可能なシナリオ

プロトタイプモードを使用してオブジェクトを作成すると、オブジェクトを直接作成するよりもパフォーマンスが大幅に向上します。これは、Objectクラスのcloneメソッドがローカルメソッドであり、特に大きなオブジェクトをコピーするときに、メモリ内のバイナリストリームを直接操作するため、パフォーマンスの違いが非常に明白です。

プロトタイプモードを使用するもう1つの利点は、オブジェクトの作成を簡素化し、ドキュメントを編集するときにコピーして貼り付けるのと同じくらい簡単にオブジェクトを作成できることです。

上記の利点があるため、同様のオブジェクトを繰り返し作成する必要がある場合は、プロトタイプモードの使用を検討できますたとえば、オブジェクトの作成プロセスがより複雑な場合やループの数が多い場合は、ループ本体にオブジェクトを作成する必要があります。

予防

  1. プロトタイプモードを使用してオブジェクトをコピーしても、クラスのコンストラクターは呼び出されません。オブジェクトのコピーはObjectクラスのcloneメソッドを呼び出すことによって行われるため、メモリ内のデータを直接コピーするため、クラスのコンストラクターは呼び出されません。コンストラクター内のコードが実行されないだけでなく、アクセス許可もプロトタイプモードでは無効です。シングルトンパターンを覚えていますか?シングルトンモードでは、コンストラクターのアクセス許可がプライベートに設定されている限り、シングルトンを実現できます。ただし、クローン方式は構築方式の権限を直接無視するため、シングルトンモードとプロトタイプモードが競合するため、特に注意して使用してください。
  2. ディープコピーとシャローコピー。Objectクラスのcloneメソッドは、オブジェクトの基本的なデータタイプのみをコピーし、配列、コンテナオブジェクト、参照オブジェクトなどはコピーしません。これは浅いコピーです。ディープコピーを実装する場合は、アレイ、コンテナオブジェクト、参照オブジェクトなどをプロトタイプモードで個別にコピーする必要があります。
1.	public class Prototype implements Cloneable {  
2.	    private ArrayList list = new ArrayList();  
3.	    public Prototype clone(){  
4.	        Prototype prototype = null;  
5.	        try{  
6.	            prototype = (Prototype)super.clone();  
7.	            prototype.list = (ArrayList) this.list.clone();  
8.	        }catch(CloneNotSupportedException e){  
9.	            e.printStackTrace();  
10.	        }  
11.	        return prototype;   
12.	    }  
} 

ArrayListは基本型ではないため、メンバー変数リストはコピーされません。自分でディープコピーを実装する必要があります。幸い、javaが提供するコンテナクラスのほとんどはCloneableインターフェイスを実装しています。したがって、ディープコピーは特に難しくありません。

PS :ディープコピーとシャローコピーの問題でjava8つの基本タイプがあり、ディープコピーそれらのカプセル化タイプ文字列タイプがあります。残りは浅いコピーです。

 

 

 

 

 

 

 

 

 

 

 

 

おすすめ

転載: blog.csdn.net/sinat_37138973/article/details/88243631