プロトタイプモデル(05)に記載のJavaデザインパターン

I.はじめにプロトタイプモデル

1、基本的な考え方

プロトタイプモデルは、スキーマ・オブジェクトを作成します属します。プロトタイプオブジェクトを与えることによって作成されたすべてのオブジェクトの種類を示し、その後、コピープロトタイプオブジェクトのアプローチと同じ種類のオブジェクトの多くを作成します。

図2に示すように、モード構造

モードを使用すると、オブジェクト自体をコピーすることによって、例の新しいインスタンスを作成することができますので、プロトタイプオブジェクトの実装は、「クローン」自身のインタフェースとすることができるが必要です。この方法は、クローニング自体を達成するために、この方法では、プロトタイプのインスタンスを通じて新しいオブジェクトを作成し、もはやあなたは新しいを作成するために通過することなく、この方法により、新しいオブジェクトを取得することができ、限り、インスタンス自体のこのタイプを気にする必要はありません。

図3に示すように、コードの実装

1)、UMLダイアグラム

プロトタイプモード(05)に記載のJavaデザインパターン
2)、中心的な役割

この形式は、3つの役割に関する:

1)顧客(クライアント)の役割:クライアント要求は、クラスのオブジェクトを作成します。

2)、抽象プロトタイプ(原型)の役割:これは、通常のJavaインタフェースまたはJava抽象クラスによって実装される抽象的役割です。このロールは、すべての必要な特定のプロトタイプクラスのインタフェースを提供します。

3)特定の原型(プロトタイプコンクリート)の役割:オブジェクトがコピーされています。この役割は、役割が必要とするインターフェイス抽象プロトタイプを実装する必要があります。

3)、JDKのソースコードに基づいて達成します

/**
 * 基于JDK源码方式实现原型模式
 */
public class C01_Property {
    public static void main(String[] args) {
        Product product = new Product("机械键盘","白色",100.00) ;
        Product product1 = (Product) product.clone();
        Product product2 = (Product) product.clone();
        System.out.println(product1);
        System.out.println(product2);
        System.out.println(product1==product2);  // false
    }
}
class Product implements Cloneable {
    private String name ;
    private String color ;
    private Double price ;
    public Product(String name, String color, Double price) {
        this.name = name;
        this.color = color;
        this.price = price;
    }
    @Override
    public String toString() {
        return "Product{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                '}';
    }
    @Override
    protected Object clone() {
        Product product = null ;
        try{
            product = (Product)super.clone() ;
        } catch (Exception e){
            e.printStackTrace();
        }
        return product ;
    }
    // 省略GET和SET方法
}

二、春Frameworkアプリケーション

1、設定ファイル

<!-- 多例Bean -->
<bean id="sheep01" class="com.model.design.spring.node05.property.Sheep" scope="prototype" />
<!-- 单例Bean 默认: scope="singleton" -->
<bean id="sheep02" class="com.model.design.spring.node05.property.Sheep"/>

2、試験ブロック

@Test
public void test01 (){
    ApplicationContext context01 = new ClassPathXmlApplicationContext(
            "/spring/spring-property.xml");
    // 原型模式
    Sheep sheep1 = (Sheep)context01.getBean("sheep01") ;
    Sheep sheep2 = (Sheep)context01.getBean("sheep01") ;
    System.out.println(sheep1==sheep2); // false
    // 单例模式
    Sheep sheep3 = (Sheep)context01.getBean("sheep02") ;
    Sheep sheep4 = (Sheep)context01.getBean("sheep02") ;
    System.out.println(sheep3==sheep4); // true
}

図3に示すように、コアのソースコード

  • ここで、クラス:org.springframework.beans.factory.support.AbstractBeanFactory
  • どこ方法:doGetBean

1)実施プロセス

if (mbd.isSingleton()) {
    sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
        public Object getObject() throws BeansException {
            try {
                return AbstractBeanFactory.this.createBean(beanName, mbd, args);
            } catch (BeansException var2) {
                AbstractBeanFactory.this.destroySingleton(beanName);
                throw var2;
            }
        }
    });
    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
    var11 = null;
    Object prototypeInstance;
    try {
        this.beforePrototypeCreation(beanName);
        prototypeInstance = this.createBean(beanName, mbd, args);
    } finally {
        this.afterPrototypeCreation(beanName);
    }
    bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} 

決意の2)、シングルトンケース

だから、デフォルトのモードは、[スコープ=「プロトタイプ」]指定された単一の実施形態では、プロトタイプモデルがされています。

public boolean isSingleton() {
    return "singleton".equals(this.scope) || "".equals(this.scope);
}
public boolean isPrototype() {
    return "prototype".equals(this.scope);
}

第三に、コピーの深さ

1、シャローコピー

1)データ型は直接浅いコピー転送値に対して、すなわち新しいコピーをオブジェクトの属性値を、基本データ型、文字列型のメンバー変数です。
2)データ型は、データの参照型メンバ変数であり、例えば、可変のメンバーは、新しいコピーにのみメンバ変数の基準値である基準浅いコピー、(メモリアドレス)によって渡される配列、オブジェクト・クラス等、ですオブジェクト。実際には、二つのオブジェクトのメンバ変数は、同じインスタンスを指します。別のオブジェクトの特性に影響を与えるオブジェクトのプロパティを変更します。
3)浅いコピーがデフォルトのクローン()メソッドを使用して行われます。

2、ディープコピー

1)概念を説明します

値に浅いコピーのコピーに加えて、コピーは、データの参照型を担当しています。他のオブジェクトを参照する変数が参照されている元のオブジェクトが、これは間接的な再生と呼ばれるオブジェクトのコピーへの参照ではなく、コピーされた新しいオブジェクトを指します。

2)ソースコードを達成します

深いクローン配列の実現

ストリームオブジェクトは、直列化(直列化)プロセスの過程であり、その目的は、デシリアライズ(デシリアライゼーション)プロセスと呼ばれるストリームプロセスから読み出されます。ストリームがオブジェクトのコピーで、元のオブジェクトは、まだ内部JVMに存在して書いたことに留意すべきです。

深いクローンオブジェクト内のJava言語では、オブジェクトが頻繁にSerializableインタフェースを作るために達成することができ、その後、オブジェクト(オブジェクトの実際のコピーだけが)ストリーム(シリアライズ)で書かれ、その後、ストリーム(デシリアライズ)からリードバック、あなたは、オブジェクトを再構築することができます。

/**
 * 深拷贝和浅拷贝对比案例
 */
public class C02_DeepClone {
    public static void main(String[] args) throws Exception {
        Dog dog = new Dog("Tom") ;
        Dog dog1 = (Dog)dog.clone() ;
        Dog dog2 = (Dog)dog.clone() ;
        // dog1:1639622804;dog2:1639622804
        System.out.println("dog1:"+dog1.cat.hashCode()+";dog2:"+dog2.cat.hashCode());
        Dog dog3 = (Dog)dog.deepClone() ;
        Dog dog4 = (Dog)dog.deepClone() ;
        // dog3:1937348256;dog4:1641808846
        System.out.println("dog3:"+dog3.cat.hashCode()+";dog4:"+dog4.cat.hashCode());
    }
}

class Cat implements Serializable {
    public String name ;
    public Cat (String name){
        this.name = name ;
    }
}
class Dog implements Cloneable,Serializable {
    public String name ;
    public Cat cat ;
    public Dog (String name){
        this.name = name ;
        this.cat = new Cat("Kit") ;
    }
    @Override
    protected Object clone() {
        Dog dog = null ;
        try{
            dog = (Dog)super.clone() ;
        } catch (Exception e){
            e.printStackTrace();
        }
        return dog ;
    }
    public Object deepClone() throws IOException, ClassNotFoundException{
        //将对象写到流里面:序列化
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        //从流里面读出对象:反序列化
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }
}

第四に、要約の長所と短所

1、の利点をまとめたもの

プロトタイプモードでは、実行時に動的に変化する特定の種類の実現を可能にします。動作中のプロトタイプモードでは、実装タイプのプロトタイプインタフェースに合わせて登録する顧客によって、また、動的に特定の実装の種類を変更することができ、インターフェースに変化がないようだが、実際には、すでにクラスの別のインスタンスを実行しています。クローンは、クラスのインスタンスのプロトタイプに似ているため。

2、欠点の要約

プロトタイプモデルの主な欠点は、各クラスがクローニング法を装備しなければならないことです。クローニング方法は、機能クラスを考慮に入れる必要がで、この新しいクラスのために難しいことではありませんが、いくつかのクラスは、クラスは間接オブジェクトの参照配列、または参照をサポートしていない場合は特に、非常に簡単ではないかもしれない持っています環状構造を含む場合。

第五に、ソースコードのアドレス

GitHub地址:知了一笑
https://github.com/cicadasmile/model-arithmetic-parent
码云地址:知了一笑
https://gitee.com/cicadasmile/model-arithmetic-parent


おすすめ

転載: www.cnblogs.com/cicada-smile/p/11261575.html