Design Pattern (3) — singleton pattern

Next: Design Pattern (5) — Builder pattern

directory

A summary,

Second, the code

Deep and shallow replication

3.1 an overview of the

3.2 code

3.2.1 Reference Replication: Directly compare references

3.2.2 Object Replication (Shallow replication, reference comparison must be false)

3.2.3 Object Replication (Deep replication, reference comparison must be false)

3.3 summary

Four,


 

A summary,

Official explanation: Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this Prototype specifies the type of object to create with prototype instances and creates new objects by copying these prototypes.

Using clone() instead of new to create objects reduces the performance cost. The requirement is deep copy, which can be done with Clone () or serialization.

Participants: AbstractPrototype class AbstractPrototype, ConcretePrototype class ConcretePrototype, Client class

Class Diagram (Client directly access ConcretePrototype) :

Class diagram (Client accesses ConcretePrototype through the Factory class) :

 

Second, the code

Code (using the prototype pattern when creating new objects) – Similar to the factory pattern, the first advantage of the prototype pattern is to reduce the performance cost of creating objects with the new keyword.

package mypackage;

import java.util.HashMap;
import java.util.Map;

public class TestPrototypePattern {

	public static void main(String[] args) {
		ShapeFactory _sShapeFactory = new ShapeFactory();
		_sShapeFactory.loadInit();
		for (int i = 0; i < 100; i++) {
			_sShapeFactory.get(i % 3 + 1).display(); }}}abstract class Shape implements Cloneable {
	@Override
	protected Object clone(a) throws CloneNotSupportedException {
		return super.clone();
	}

	abstract void display(a);
}

class Circle extends Shape {

	@Override
	void display(a) {
		System.out.println("This is a Circle"); }}class Rectangle extends Shape {

	@Override
	void display(a) {
		System.out.println("This is a Rectangle"); }}class Square extends Shape {

	@Override
	void display(a) {
		System.out.println("This is a Square"); }}class ShapeFactory {
	private Map<Integer, Shape> shapeList = new HashMap<>();

	public void loadInit(a) {
		shapeList.put(1.new Circle());
		shapeList.put(2.new Rectangle());
		shapeList.put(3.new Square());
	}

	public Shape get(int id) {
		Shape shape = shapeList.get(id);
		try {
			return (Shape) shape.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return null; }}Copy the code

Output:

This is a Circle
This is a Rectangle
This is a Square
This is a Circle
This is a Rectangle
This is a Square
......
Copy the code

Summary: Using prototype mode is better than factory mode when creating new objects. It can reduce the performance cost of new objects. For objects that contain references, clone() or serialization can be used to achieve deep replication, with the object attribute values passed in by the client.

Deep and shallow replication

3.1 an overview of the

Java replication includes reference replication and object replication. Object replication includes shallow replication and deep replication.

Reference copy  
Object replication A shallow copy
Deep copy

3.2 code

3.2.1 Reference Replication: Directly compare references

Student student2 = Student;

public class CopyTest {

	public static void main(String[] args) {
		Student student = newStudent(); Student student2 = student; System.out.println(student); System.out.println(student2); System.out.println(student == student2); }}class Student {}Copy the code

Output:

mypackage.Student@15db9742
mypackage.Student@15db9742
true
Copy the code

Summary: Reference copy. The copied reference points to the same object address as the original reference.

3.2.2 Object Replication (Shallow replication, reference comparison must be false)

3.2.2.1 Shallow Replication (Implement the Clonable interface to override the clone() function)

package mypackage;

public class CopyTest {

	public static void main(String[] args) throws Exception {
		Student student = new Student();
		student.setName("Xiao Ming");
		student.set_age(18);
		Sex _sSex = new Sex();
		_sSex.setSex("Male");
		student.setSex(_sSex);
		Address _dAddress = new Address();
		_dAddress.setProvince("Guangdong province");
		_dAddress.setCity("Guangzhou");
		student.set_address(_dAddress);

		System.out.println(Student:" + student);

		Student student2 = (Student) student.clone();
		student2.setName("Little red");
		student2.set_age(20);
		
		student2.getSex().setSex("Female");
		
		student2.get_address().setProvince("Hunan Province");
		student2.get_address().setCity("Changsha");

		System.out.println(Student:" + student);
		System.out.println("Student2:" + student2);
		System.out.println("Are references equal:"+(student == student2)); }}class Student implements Cloneable {
	private String name;
	private int _age;
	private Sex sex;
	private Address _address;

	public String getName(a) {
		return name;
	}

	public Sex getSex(a) {
		return sex;
	}

	public void setSex(Sex sex) {
		this.sex = sex;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int get_age(a) {
		return _age;
	}

	public void set_age(int _age) {
		this._age = _age;
	}

	public Address get_address(a) {
		return _address;
	}

	public void set_address(Address _address) {
		this._address = _address;
	}

	@Override
	public String toString(a) {
		return "Student [name=" + name + ", _age=" + _age + ", sex=" + sex + ", _address=" + _address + "]";
	}

	@Override
	protected Object clone(a) throws CloneNotSupportedException {
		return super.clone(); }}class Sex {
	private String sex;

	public String getSex(a) {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	@Override
	public String toString(a) {
		return "Sex [sex=" + sex + "]"; }}class Address {
	private String province;
	private String city;

	public String getProvince(a) {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public String getCity(a) {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	@Override
	public String toString(a) {
		return "Address [province=" + province + ", city=" + city + "]"; }}Copy the code

Output:

Alter table student: student [name= student, _age=18, sex= sex [sex= male], _address=Address [province= guangdong, city= Guangzhou]] modify student: student [name= xiaoming, _age=18, sex= sex [sex= female], _address=Address [province= hunan, city= Changsha]] student2: Student [name= xiaored, _age=20, sex= sex [sex= female], _address=Address [province= Hunan, city= Changsha]]false
Copy the code

Clone is a non-final method that comes with Object and is native by default, so we need to inherit the Clonable interface before overriding the Clone () method, which is the basis for Object replication (both shallow and deep).

3.2.2.2 Shallow Copy (Using constructors for Shallow Copy)

package mypackage;

public class CopyTest {

	public static void main(String[] args) throws Exception {
		Student student = new Student();
		student.setName("Xiao Ming");
		student.set_age(18);
		Sex _sSex = new Sex();
		_sSex.setSex("Male");
		student.setSex(_sSex);
		Address _dAddress = new Address();
		_dAddress.setProvince("Guangdong province");
		_dAddress.setCity("Guangzhou");
		student.set_address(_dAddress);

		System.out.println(Student:" + student);

		Student student2 = new Student(student);
		student2.setName("Little red");
		student2.set_age(20);
	

		
		student2.getSex().setSex("Female");
		
		student2.get_address().setProvince("Hunan Province");
		student2.get_address().setCity("Changsha");
		
		
		System.out.println(Student:" + student);
		System.out.println("Student2:" + student2);
		System.out.println("Are references equal:"+(student == student2)); }}class Student  {
	private String name;
	private int _age;
	private Sex sex;
	private Address _address;

	public String getName(a) {
		return name;
	}

	public Sex getSex(a) {
		return sex;
	}

	public void setSex(Sex sex) {
		this.sex = sex;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int get_age(a) {
		return _age;
	}

	public void set_age(int _age) {
		this._age = _age;
	}

	public Address get_address(a) {
		return _address;
	}

	public void set_address(Address _address) {
		this._address = _address;
	}

	@Override
	public String toString(a) {
		return "Student [name=" + name + ", _age=" + _age + ", sex=" + sex + ", _address=" + _address + "]";
	}

	public Student(Student student) {
		this.name=student.name;
		this._age=student._age;
		this.sex=student.sex;
		this._address=student._address;
	}

	public Student(a) {
		super();
	}


}

class Sex {
	private String sex;

	public String getSex(a) {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	@Override
	public String toString(a) {
		return "Sex [sex=" + sex + "]"; }}class Address {
	private String province;
	private String city;

	public String getProvince(a) {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public String getCity(a) {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	@Override
	public String toString(a) {
		return "Address [province=" + province + ", city=" + city + "]"; }}Copy the code

Output:

Alter table student: student [name= student, _age=18, sex= sex [sex= male], _address=Address [province= guangdong, city= Guangzhou]] modify student: student [name= xiaoming, _age=18, sex= sex [sex= female], _address=Address [province= hunan, city= Changsha]] student2: Student [name= xiaored, _age=20, sex= sex [sex= female], _address=Address [province= Hunan, city= Changsha]]false
Copy the code

Summary:

1. Shallow replication can be implemented in two ways: implement the Clonable interface and use the clone() function, and shallow replication in the constructor.

2. Features of shallow replication:

For basic type data, the copy uses value passing, because the passed is the value, so after the copy is modified, the original is not affected;

For reference type data, the copy uses reference passing, because the reference is passed (that is, the memory address), which actually points to the same object as the copy, so after the copy changes, the original will also change.

3.2.3 Object Replication (Deep replication, reference comparison must be false)

3.2.3.1 Deep Replication (implement the Clonable interface to override the clone() method)

package mypackage;

public class CopyTest {

	public static void main(String[] args) throws Exception {
		Student student = new Student();
		student.setName("Xiao Ming");
		student.set_age(18);
		Sex _sSex = new Sex();
		_sSex.setSex("Male");
		student.setSex(_sSex);
		Address _dAddress = new Address();
		_dAddress.setProvince("Guangdong province");
		_dAddress.setCity("Guangzhou");
		student.set_address(_dAddress);

		System.out.println(Student:" + student);

		Student student2 = (Student) student.clone();
		student2.setName("Little red");
		student2.set_age(20);


		student2.getSex().setSex("Female");


		student2.get_address().setProvince("Hunan Province");
		student2.get_address().setCity("Changsha");

		System.out.println(Student:" + student);
		System.out.println("Student2:" + student2);
		System.out.println("Are references equal:"+(student == student2)); }}class Student implements Cloneable {
	private String name;
	private int _age;
	private Sex sex;
	private Address _address;

	public String getName(a) {
		return name;
	}

	public Sex getSex(a) {
		return sex;
	}

	public void setSex(Sex sex) {
		this.sex = sex;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int get_age(a) {
		return _age;
	}

	public void set_age(int _age) {
		this._age = _age;
	}

	public Address get_address(a) {
		return _address;
	}

	public void set_address(Address _address) {
		this._address = _address;
	}

	@Override
	public String toString(a) {
		return "Student [name=" + name + ", _age=" + _age + ", sex=" + sex + ", _address=" + _address + "]";
	}

	@Override
	protected Object clone(a) throws CloneNotSupportedException {
		Student _newStudent = (Student) super.clone();
		_newStudent.sex = (Sex) sex.clone();
		_newStudent._address = (Address) _address.clone();
		return_newStudent; }}class Sex implements Cloneable {
	private String sex;

	public String getSex(a) {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	@Override
	public String toString(a) {
		return "Sex [sex=" + sex + "]";
	}

	@Override
	protected Object clone(a) throws CloneNotSupportedException {
		return super.clone(); }}class Address implements Cloneable {
	private String province;
	private String city;

	public String getProvince(a) {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public String getCity(a) {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	@Override
	public String toString(a) {
		return "Address [province=" + province + ", city=" + city + "]";
	}

	@Override
	protected Object clone(a) throws CloneNotSupportedException {
		return super.clone(); }}Copy the code

Output:

Alter table student: student [name= student, _age=18, sex= sex [sex= male], _address=Address [province= guangdong, city= Guangzhou]] modify student: student [name= xiaoming, _age=18, sex= sex [sex= male], _address=Address [province= guangdong, city= Guangdong]] student2: Student [name= xiaohong, _age=20, sex= sex [sex= female], _address=Address [province= Hunan, city= Changsha]]false
Copy the code

3.2.3.2 Deep Replication (Serialization for Deep Replication)

If the clone method was injected with the class object, you would have to clone the clone method for each reference object.

package mypackage;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class CopyTest {

	public static void main(String[] args) throws Exception {
		Student student = new Student();
		student.setName("Xiao Ming");
		student.set_age(18);
		Sex _sSex = new Sex();
		_sSex.setSex("Male");
		student.setSex(_sSex);
		Address _dAddress = new Address();
		_dAddress.setProvince("Guangdong province");
		_dAddress.setCity("Guangzhou");
		student.set_address(_dAddress);

		System.out.println(Student:" + student);

		Student student2 = (Student) student.deepCopy();
		student2.setName("Little red");
		student2.set_age(20);

		student2.getSex().setSex("Female");


		student2.get_address().setProvince("Hunan Province");
		student2.get_address().setCity("Changsha");

		System.out.println(Student:" + student);
		System.out.println("Student2:" + student2);
		System.out.println("Are references equal:"+(student == student2)); }}class Student implements Serializable {
	private static final long serialVersionUID = 1L;
	private String name;
	private int _age;
	private Sex sex;
	private Address _address;

	public String getName(a) {
		return name;
	}

	public Sex getSex(a) {
		return sex;
	}

	public void setSex(Sex sex) {
		this.sex = sex;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int get_age(a) {
		return _age;
	}

	public void set_age(int _age) {
		this._age = _age;
	}

	public Address get_address(a) {
		return _address;
	}

	public void set_address(Address _address) {
		this._address = _address;
	}

	@Override
	public String toString(a) {
		return "Student [name=" + name + ", _age=" + _age + ", sex=" + sex + ", _address=" + _address + "]";
	}

	public Object deepCopy(a) throws Exception {
		ByteArrayOutputStream _bByteArrayOutputStream = new ByteArrayOutputStream();
		ObjectOutputStream _bObjectOutputStream = new ObjectOutputStream(_bByteArrayOutputStream);
		_bObjectOutputStream.writeObject(this);

		ByteArrayInputStream _bByteArrayInputStream = new ByteArrayInputStream(_bByteArrayOutputStream.toByteArray());
		ObjectInputStream _bObjectInputStream = new ObjectInputStream(_bByteArrayInputStream);
		return_bObjectInputStream.readObject(); }}class Sex implements Serializable {

	private static final long serialVersionUID = 1L;
	private String sex;

	public String getSex(a) {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	@Override
	public String toString(a) {
		return "Sex [sex=" + sex + "]"; }}class Address implements Serializable {
	private static final long serialVersionUID = 1L;
	private String province;
	private String city;

	public String getProvince(a) {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public String getCity(a) {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	@Override
	public String toString(a) {
		return "Address [province=" + province + ", city=" + city + "]"; }}Copy the code

Output:

Alter table student: student [name= student, _age=18, sex= sex [sex= male], _address=Address [province= guangdong, city= Guangzhou]] modify student: student [name= xiaoming, _age=18, sex= sex [sex= male], _address=Address [province= guangdong, city= Guangdong]] student2: Student [name= xiaohong, _age=20, sex= sex [sex= female], _address=Address [province= Hunan, city= Changsha]]false
Copy the code

Summary:

1. Two implementations of deep replication: Clone () method and serialization

2. Deep copy features: Both basic and reference types have been completely created in memory, so when the copy is modified, the original copy is not affected, and vice versa.

3.3 summary

Whether reference copy, shallow copy or deep copy, is a basic syntax in Java, and a good command of Java basic syntax will lay a good foundation for subsequent Java learning.

Four,

Application of prototype mode:

1. When a large number of objects of a class are needed, using the prototype mode is the best choice, because the prototype mode copies the object in memory, which is much better than directly new the object. In this case, the more objects are needed, the more obvious the advantages of the prototype mode.

2. Prototype mode can be used if the initialization of an object requires tedious calculations of data preparation for many other objects or other resources.

3. When a large amount of public information of an object and a small number of fields are needed for personalized Settings, the prototype mode can also be used to copy a copy of the object for processing.

 

Design Pattern (3) — singleton pattern

Next: Design Pattern (5) — Builder pattern