padrão de design (14) - padrões de protótipo (Protótipo)

definição do conceito

Exemplos de um protótipo a ser criado para especificar o tipo do objeto, e para criar novos objetos copiando este protótipo. Prototype modelo de protótipo objeto permite que um clone (cópia) uma pluralidade de objetos idticas, sem ter que saber todos os detalhes de como criar.

cenários

  • A criação de objetos para criar mais complexos e exigem freqüentes
  • É desejável gerar uma nova instância de acordo com um exemplo convencional, por exemplo:
    • Quando uma grande variedade de objetos não podem ser integrados em uma classe
    • Quando é difícil de especificar o nome da classe gerada pela instância
    • Exemplos do quadro gerado quando o desacoplamento desejados

Em aplicações práticas, modelos de protótipos raramente ocorrem isoladamente. Muitas vezes misturada com outros modos.

implementação do protótipo

Todas as classes herdam de Java java.lang.Object, e classe de objeto fornece o método clone () para objetos de clone. Deste modo, a classe Java que implementa a interface e reescreve clone Cloneable () método, pode ser realizado padrão Protótipo .

Prototype exemplo padrão de código da seguinte forma:

// 原型类(也可定义为interface Prototype extends Cloneable)
abstract class Prototype implements Cloneable {
    private String name;
    public void setName(String name) {this.name = name;}
    public String getName() {return this.name;}

    public abstract void doSomething();

    @Override
    public Object clone() { // clone()方法用public修饰
        Object object = null;
        try {
            object = super.clone(); // 调用父类clone()方法
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return object;
    }
}

// 具体实现类(继承自Prototype类自动具有克隆功能)
class ConcretePrototype extends Prototype{
    public ConcretePrototype() { setName("ConcretePrototype"); }

    @Override
    public void doSomething() { System.out.println("I'll clone myself!"); }
}

public class PrototypeDemo {
    public static void main(String[] args) {
        ConcretePrototype cp = new ConcretePrototype();
        cp.doSomething();

        for(int i=0; i< 5; i++){
            ConcretePrototype cloned = (ConcretePrototype)cp.clone();
            System.out.println("I'm cloned by " + cloned.getName());
        }
    }
}

Depois de realizar o seguinte resultado:

I'll clone myself!
I'm cloned by ConcretePrototype
I'm cloned by ConcretePrototype
I'm cloned by ConcretePrototype
I'm cloned by ConcretePrototype
I'm cloned by ConcretePrototype

O modo de vantagens e desvantagens

padrão Prototype seguintes vantagens:

  • Dependendo dos requisitos do cliente para dinâmico objetos para criar em tempo de execução do cliente não precisa saber os detalhes de objetos, criando, fácil de manter e expandir código.
  • Ao criar um objecto para criar mais complexo ou repetida um grande número de objectos semelhantes, o objectivo é criar simplificado, e o desempenho (irá chamar automaticamente toda a nova cadeia Construtor, mas não põe qualquer método construtor classe clone) mais elevada do que os novos objectos directamente .
  • padrão protótipo semelhante ao modo de fábrica, mas não há relação hierárquica abstratas plantas modelo de fábrica e código específico de planta estrutura mais clara e mais simples.

Deficiências são as seguintes:

  • Require () deve ser modificado para cada interface Cloneable implementos de classe e substituir o método clone quando, alterando a classe existente de sua fonte, ao contrário do "princípio de abertura e fechamento."
  • Singleton e modelo de fábrica, protótipos estão em conflito, tente não misturar.
  • Ao implementar uma necessidade cópia profunda (clone de profundidade) para escrever o código complicado.

precauções

clone () método de copiar apenas os tipos de objectos de dados de base, sem copiar a matriz, o objeto de recipiente, a referência de objecto e semelhantes. Para alcançar cópia profunda, você deve Protótipo modo de matriz, o objeto de contêiner, objeto de referência como uma cópia separada .
Outros objectos, por exemplo, quando uma cópia em profundidade do objecto, o objecto tem de implementar a interface Cloneable e método clone de sobreposição (), e o objecto no interior do método clone de referência () é também um clone. Da mesma forma, o objecto referido também fazer o mesmo processo.
Nota, Boolean, Byte, caráter, classe , Double, Float, Integer, Long, Short, String , e na maioria das subclasses de excepção são classe imutável, não é necessário implementar uma cópia profunda do objeto. Além disso, a maioria das classes de Java recipiente ter sido alcançado função clonagem.

Em contraste, o clone () método é mais adequado para uma variedade de cópia em profundidade. Mas note os dois pontos seguintes:

(1) tipos básicos de matriz unidimensional por tais (int[])data.clone()formas de clonagem, o tipo de base de "matriz bidimensional" (na realidade, como um tipo int [] representa uma matriz unidimensional) necessária por Wei Kelong. Por exemplo:

public static int[][] twoDimensionArrayClone (int[][] tdArray){
    int[][] copy = tdArray.clone();
    for (int i = 0; i < tdArray.length; i++) {
        copy[i] = tdArray[i].clone();
    }
    return copy;
}

(2) Quando os elementos da matriz a objectos Java comum, mas também a matriz clone clonado contido na matriz. Os exemplos a seguir mostram em detalhes as diferentes maneiras de rasas vs. cópia profunda da matriz de objetos:

class Person implements Cloneable {
    public String name;
    public Person(String name) {this.name = name;}

    @Override
    public Object clone() {
        Object object = null;
        try {
            object = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return object;
    }
}

public class ArrayPrototype {
    public static void main(String[] args) {
		Person[] origin = new Person[] { new Person("Mike"), new Person("Jack"), new Person("Jason") };
		Person[] copyOf = Arrays.copyOf(origin, origin.length);
		// 浅拷贝(内部调用System.arraycopy,返回新数组)
		Person[] arrayCopy = new Person[origin.length];
		// 浅拷贝(可拷贝部分数组)
		System.arraycopy(origin, 0, arrayCopy, 0, origin.length);
		Person[] clonedCopy = origin.clone();
		// 浅拷贝
		System.out.println("origin=copyOf=arrayCopy=clonedCopy="
				+ (origin[0] == copyOf[0] && copyOf[1] == arrayCopy[1] && arrayCopy[2] == clonedCopy[2]));
		clonedCopy[0].name = "Lily";
		System.out.println("Shallow Person[0]: " + origin[0].name + " -> " + clonedCopy[0].name);

		Person[] deepCopy = new Person[origin.length];
		// 深拷贝
		for (int i = 0; i < origin.length; i++) {
			deepCopy[i] = (Person) origin[i].clone();
		}
		deepCopy[1].name = "Lily";
		System.out.println("Deep Person[1]: " + origin[1].name + " -> " + clonedCopy[1].name);
		Person[] deepCopy2 = Arrays.stream(origin).map(Person::clone).toArray(Person[]::new);
		// 深拷贝
		deepCopy2[2].name = "Lucy";
		System.out.println("Deep Person[2]: " + origin[2].name + " -> " + deepCopy2[2].name);
	}
}

práticas da indústria

  • Ação Objects (Struts2)
  • exemplo feijão (Primavera) protótipo criado
Publicado 295 artigos originais · ganhou elogios 37 · vê 30000 +

Acho que você gosta

Origin blog.csdn.net/tianshan2010/article/details/104722260
Recomendado
Clasificación