Android design mode (iii)-prototype mode

Source: Internet
Author: User

Prototype mode is also a creation of a design pattern, from the name can be understood, this pattern should have a template instance, that is, the prototype, and then the user from the prototype copy of an internal attribute consistent instance, that is, cloning.
Sometimes, when an object is constructed more complex and time-consuming, it is more efficient to copy an instance directly from an existing object than to reconstruct it.

Jane's book Address

Defined

Use the prototype instance to specify the kind of object to create and create a new object by copying the prototypes.

Usage Scenarios
    • Initialization of objects consumes a lot of resources, including hardware, data, and so on. You can use prototype mode to avoid the consumption of this resource.
    • You can use prototype mode when you instantiate an object with new to require very tedious data preparation or access permissions.
    • When an object is to be accessed by other objects, and each caller is likely to modify his value, consider copying multiple prototypes of objects in prototype mode for use by each caller, without affecting each other, that is, a protective copy.
    • When you need to create similar objects frequently, such as creating objects in a loop.

This shows that using clone to produce an instance is not necessarily faster than new, and when some objects are constructed very simply, new is faster than clone. However, when the construction of the object is complicated, the new structure will cause a large cost, then clone can show the advantage of efficiency.

UML Class Diagram


Where prototype does not have to implement the Cloneable interface, there are two types of presentations.

Simple implementation using the Cloneable interface

Prototype to implement the Cloneable interface:

publicclass Prototype implements Cloneable{ }

The implementation of the prototype:

 Public  class concreteprototype extends Prototype {     PublicString name; Publicarraylist<string> list =NewArraylist<> (); Public Concreteprototype() {System.out.println ("Concreteprototype Constructor was executed"); }@Override     PublicConcreteprototypeClone() {Concreteprototype prototype =NULL;Try{prototype = (Concreteprototype)Super. Clone (); }Catch(Clonenotsupportedexception e)        {E.printstacktrace (); }returnPrototype }@Override     PublicStringtoString() {return "concreteprototype{"+"Name= '"+ name +' \ '+", list="+ list +'} '; }}

Use:

public class Mainm {public static void main (string[] args) {Concreteprototype Concreteprototype = new Concrete Prototype ();Concreteprototype. Name="Yuanxing";Concreteprototype. List. Add("Yuanxing1");Concreteprototype. List. Add("Yuanxing2");Concreteprototype. List. Add("Yuanxing3");Concreteprototype Cloneconcreteprototype = (concreteprototype) concreteprototype. Clone();Cloneconcreteprototype. Name="Clone";System. out. println(Concreteprototype. toString());System. out. println(Cloneconcreteprototype. toString());}}

Output:

An instance is obtained by using the Clone method, and modifying the contents of the instance does not affect the contents of the original instance.
This, of course, is only valid for basic data types.

Do not implement Cloneable interface

Prototype:

publicclass Prototype1 {}

The implementation of the prototype:

 Public  class ConcretePrototype1 extends Prototype1 {     PublicString name; Publicarraylist<string> list =NewArraylist<> (); Public ConcretePrototype1() {System.out.println ("Concreteprototype Constructor was executed"); } PublicConcretePrototype1Clone() {ConcretePrototype1 prototype1 =NewConcretePrototype1 (); Prototype1.name = This. Name; prototype1.list= This. List;returnPrototype1; }@Override     PublicStringtoString() {return "concreteprototype1{"+"Name= '"+ name +' \ '+", list="+ list +'} '; }}

Use:

public class Mainm {public static void main (string[] args) {ConcretePrototype1 concretePrototype1 = new Concre TePrototype1 ();ConcretePrototype1. Name="Yuanxing";ConcretePrototype1. List. Add("Yuanxing1");ConcretePrototype1. List. Add("Yuanxing2");ConcretePrototype1. List. Add("Yuanxing3");ConcretePrototype1 cloneconcretePrototype1 = (ConcretePrototype1) concretePrototype1. Clone();CloneconcretePrototype1. Name="Clone";System. out. println(ConcretePrototype1. toString());System. out. println(CloneconcretePrototype1. toString());}}

The result of the output is a bit different:

The method of calling Cloneable directly does not call the construction method again, and your new is bound to call the constructor method.
I personally think this should be a pseudo-clone, just write a clone method, and then in the method to new an object, and then to manually assign their own value to the new object.

Problem

All two of the above tests the Name property, what if the ArrayList object list is modified in the cloned object? To try:
Use:

public class Mainm {public static void main (string[] args) {Concreteprototype Concreteprototype = new Concrete Prototype ();Concreteprototype. Name="Yuanxing";Concreteprototype. List. Add("Yuanxing1");Concreteprototype. List. Add("Yuanxing2");Concreteprototype. List. Add("Yuanxing3");Concreteprototype Cloneconcreteprototype = (concreteprototype) concreteprototype. Clone();Cloneconcreteprototype. Name="Clone";Cloneconcreteprototype. List. Add("Clone1");System. out. println(Concreteprototype. toString());System. out. println(Cloneconcreteprototype. toString());}}

The discovery output is not expected:

A list of cloned objects has been modified, and the value of list in the prototype has changed.

Deep copy-Shallow copy

This occurs because a shallow copy is used in the previous prototype. Cloneable method Clone is a shallow copy by default, and a shallow copy does not reconstruct all the fields, but refers to the fields in the prototype. For value types, which are basic data types, there is also a string type, and the Clone method makes a copy that allows the copied objects and prototypes to interfere with each other. However, for reference types (objects, collections, arrays, and so on), the Clone method simply points them to the same memory address, so modifying one of them will change the contents of each of the two.
So for a property that is not of the base type, you manually invoke the Clone method of the Reference object at clone, which is a deep copy.
Add a deep copy of the overridden Clone method

@Override    publicclone()  {        null;        try {            super.clone();            this.list.clone();        catch (CloneNotSupportedException e) {            e.printStackTrace();        }        return prototype;    }

Then we will get the output we expect:

Prototype mode in Android Source:

The prototype pattern may rarely be used alone, in the case of the book is a intent, although the Cloneable interface is implemented, but in the Clone method is a direct new intent, the prototype is passed in, and then copied to the new intent:

 PackageAndroid.content; Public  class Intent implements parcelable, cloneable {    /** * Copy constructor * /     Public Intent(Intent o) { This. maction = o.maction; This. Mdata = O.mdata; This. mtype = O.mtype; This. mpackage = O.mpackage; This. mcomponent = o.mcomponent; This. mflags = O.mflags; This. Mcontentuserhint = O.mcontentuserhint;if(O.mcategories! =NULL) { This. mcategories =NewArrayset<string> (o.mcategories); }if(O.mextras! =NULL) { This. Mextras =NewBundle (O.mextras); }if(O.msourcebounds! =NULL) { This. Msourcebounds =NewRect (O.msourcebounds); }if(O.mselector! =NULL) { This. Mselector =NewIntent (O.mselector); }if(O.mclipdata! =NULL) { This. Mclipdata =NewClipdata (O.mclipdata); }    }@Override     PublicObjectClone() {return NewIntent ( This); }    }

What you might consider here is that direct new is faster than clone.

Summarize

Prototype mode is mainly copying objects, copying objects generally have two functions
1. The protection prototype is not modified, providing only one copy for external access, and a protective copy.
2. Avoid the problem of resource consumption when constructing complex objects, and improve the efficiency of creating objects.

Advantages
    • The Clone method of object is a local method that directly operates on a binary stream and performs much better.
Disadvantages
    • The construction method will not be executed at clone, which is both an advantage and a disadvantage, and should be paid attention to when using this potential problem.

Android design mode (iii)-prototype mode

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.