Design Pattern 10-Prototype)

Source: Internet
Author: User
1. Scenario Mode

Consider this practical application: Order Processing System
There is a function to save the order. When the number of products exceeds 1000, split the order into two orders. There are two types of orders until each order is no more than 1000. One is a personal order and the other is a company order. Now a general order processing system is required.
2. Scene mode code (the code is very simple and I will not explain it one by one)

Package demo08.prototype. example1;/*** order interface */public interface orderapi {/*** get order product quantity *** @ return product quantity in order */Public int getorderproductnum (); /*** set the order product quantity ** @ Param num * Order product quantity */Public void setorderproductnum (INT num );}
Package demo08.prototype. example1;/*** personal order object */public class personalorder implements orderapi {/*** name of ordering personnel */private string customername; /*** product ID */private string productid;/*** order product quantity */private int orderproductnum = 0; Public int getorderproductnum () {return this. orderproductnum;} public void setorderproductnum (INT num) {This. orderproductnum = num;} Public String getcustomername () {return customername;} public void setcustomername (string customername) {This. customername = customername;} Public String getproductid () {return productid;} public void setproductid (string productid) {This. productid = productid;} Public String tostring () {return "the orderer of this individual order is =" + this. customername + ", the purchased product is =" + this. productid + ", order quantity =" + this. orderproductnum ;}}
Package demo08.prototype. example1;/*** Enterprise Order object */public class incluiseorder implements orderapi {/*** enterprise name */private string incluisename; /*** product ID */private string productid;/*** order product quantity */private int orderproductnum = 0; Public int getorderproductnum () {return this. orderproductnum;} public void setorderproductnum (INT num) {This. orderproductnum = num;} Public String getincluisename () {return incluisename;} public void setincluisename (string incluisename) {This. enterprisename = enterprisename;} Public String getproductid () {return productid;} public void setproductid (string productid) {This. productid = productid;} Public String tostring () {return "the order of this enterprise order is =" + this. enterprisename + ", the purchased product is =" + this. productid + ", order quantity =" + this. orderproductnum ;}}
Package demo08.prototype. example1; /*** Business Object for processing orders */public class orderbusiness {/*** method for creating orders ** @ Param Order * interface object of orders */Public void saveorder (orderapi order) {// according to business requirements, when the number of products in the order exceeds 1000, You need to split the order into two orders. // Of course, if you want to do well, here 1000 should be made a constant, so as to demonstrate simple // 1: determine whether the current number of pre-defined products is greater than 1000 while (Order. getorderproductnum ()> 1000) {// 2, all others share the same orderapi neworder = NULL; If (Order instanceof personalorder) {// create the corresponding new order object personalorder P2 = new personalorder (); // then assign values, however, the product quantity is 1000 personalorder p1 = (personalorder) Order; p2.setcustomername (p1.getcustomername (); p2.setproductid (p1.getproductid (); p2.setorderproductnum (1000 ); // then set it to neworderneworder = P2;} else if (Order instanceof incluiseorder) {// create the corresponding order object incluiseorder e2 = new incluiseorder (); // then assign a value, however, the number of products is 1000 enterpriseorder e1 = (enterpriseorder) Order; e2.setenterprisename (e1.getenterprisename (); e2.setproductid (e1.getproductid (); e2.setorderproductnum (1000 ); // then set it to neworderneworder = e2;} // 2.2 the original order is retained and the quantity is reduced by 1000order. setorderproductnum (Order. getorderproductnum ()-1000); // then, the service function is processed. If it is omitted, print the output and check the system. out. println ("split to generate order =" + neworder);} // 3: no more, so you can directly process the business functions. If this parameter is omitted, print the output and check system. out. println ("Order =" + order);} // public void saveorder2 (orderapi order) {// int oldnum = order. getorderproductnum (); // while (oldnum> 1000) {// defines a new order object that is split. // orderapi neworder = NULL; //// if (Order instanceof personalorder) {//// create the corresponding order object // personalorder P2 = new personalorder (); /// then assign values, skipped // and then set it to neworder // neworder = P2; //} else if (Order instanceof policiseorder) {//// create the corresponding order object // incluiseorder e2 = new incluiseorder (); // then assign values, etc, /// is omitted and then set to neworder // neworder = e2; // then split and process other business functions, skipped //}//}}
Package demo08.prototype. example1; public class orderclient {public static void main (string [] ARGs) {// create an order object. Here, to demonstrate the simplicity, the new personalorder op = new personalorder (); // set the order data op. setorderproductnum (2925); OP. setcustomername ("Zhang San"); OP. setproductid ("p0001"); // here, the class for business processing is obtained, and it is new directly. For simplicity, no orderbusiness Ob = new orderbusiness () is made for the business interface (); // call the business to save the order object ob. saveorder (OP );}}
3. Problem

After careful observation, we can find that the order type and implementation are concerned. The evidence is as follows:

// 1: determine whether the current number of products is greater than 1000 while (Order. getorderproductnum ()> 1000) {// 2, all others share the same orderapi neworder = NULL; If (Order instanceof personalorder) {// create the corresponding new order object personalorder P2 = new personalorder (); // then assign values, however, the product quantity is 1000 personalorder p1 = (personalorder) Order; p2.setcustomername (p1.getcustomername (); p2.setproductid (p1.getproductid (); p2.setorderproductnum (1000 ); // then set it to neworderneworder = P2;} else if (Order instanceof incluiseorder) {// create the corresponding order object incluiseorder e2 = new incluiseorder (); // then assign a value, however, the number of products is 1000 enterpriseorder e1 = (enterpriseorder) Order; e2.setenterprisename (e1.getenterprisename (); e2.setproductid (e1.getproductid (); e2.setorderproductnum (1000 ); // then set it to neworderneworder = e2;} // 2.2 the original order is retained and the quantity is reduced by 1000order. setorderproductnum (Order. getorderproductnum ()-1000); // then, the service function is processed. If it is omitted, print the output and check the system. out. println ("split to generate order =" + neworder );}
4. Solution

Do you think the above code is very bloated, uncomfortable, and uncomfortable? It indicates that you have begun to understand the benefits of the Java design pattern.
The solution is to use the prototype.
5. prototype mode 5.1 prototype mode definition:

Use a prototype instance to specify the type of the object to be created, and copy the prototype to create a new object.
5.2 how to solve this problem

How can this problem be solved? Have you ever thought about putting the copied code in the interface and returning the interface object, as if the interface has created an interface object. In addition, the client does not need to understand some operations of the object, and the knowledge is minimized.
6. prototype mode sample code 6.1 mode structure diagram

 
6.2 declare an interface for cloning itself

Package demo08.prototype. example2; /*** declare a clone interface */public interface prototype {/*** clone method * @ return a cloned object */Public prototype clone ();}
6.3 specific implementation object
Package demo08.prototype. example2;/*** specific implementation object for cloning */public class concreteprototype1 implements prototype {public prototype clone () {// The simplest clone, creating a new own object, because no attribute exists, prototype = new concreteprototype1 (); Return prototype ;}} package demo08.prototype is not copied. example2;/*** specific implementation object for cloning */public class concreteprototype2 implements prototype {public prototype clone () {// The simplest clone, creating a new own object, because no attribute exists, prototype = new concreteprototype2 (); Return prototype ;}} is not copied ;}}
6.4 Client
Package demo08.prototype. example2;/*** use the prototype client */public class client {/*** to hold the required prototype interface object */private prototype;/*** constructor, input the required prototype interface object ** @ Param prototype * the required prototype interface object */Public client (prototype) {This. prototype = prototype;}/*** indicates a method to execute a function operation */Public void operation () {// prototype newprototype = prototype is required for the object of the prototype interface. clone ();}}
7. Rewrite the sample code in prototype mode

For convenience, I will directly write the changes.
7.1 order Interface

Package demo08.prototype. example3;/*** order interface, declared the clone method */public interface orderapi {/*** obtain the order product quantity * @ return the number of products in the order */Public int getorderproductnum (); /*** set the order product quantity ** @ Param num order product quantity */Public void setorderproductnum (INT num ); /*** clone method ** @ return instance of the Order prototype */Public orderapi cloneorder ();}
7.2 individual orders
Package demo08.prototype. example3;/*** personal order object */public class personalorder implements orderapi {/*** name of the ordering personnel */private string customername; /*** product ID */private string productid;/*** order product quantity */private int orderproductnum = 0; Public int getorderproductnum () {return this. orderproductnum;} public void setorderproductnum (INT num) {This. orderproductnum = num;} Public String getcustomername () {return customername;} public void setcustomername (string customername) {This. customername = customername;} Public String getproductid () {return productid;} public void setproductid (string productid) {This. productid = productid;} Public String tostring () {return "the orderer of this individual order is =" + this. customername + ", the purchased product is =" + this. productid + ", order quantity =" + this. orderproductnum;} public orderapi cloneorder () {// create a new order, and then copy the data of this instance to personalorder order = new personalorder (); Order. setcustomername (this. customername); Order. setproductid (this. productid); Order. setorderproductnum (this. orderproductnum); return order ;}}
7.3 enterprise orders
Package demo08.prototype. example3;/*** Enterprise Order object */public class incluiseorder implements orderapi {/*** enterprise name */private string incluisename; /*** product ID */private string productid;/*** order product quantity */private int orderproductnum = 0; Public int getorderproductnum () {return this. orderproductnum;} public void setorderproductnum (INT num) {This. orderproductnum = num;} Public String getincluisename () {return incluisename;} public void setincluisename (string incluisename) {This. enterprisename = enterprisename;} Public String getproductid () {return productid;} public void setproductid (string productid) {This. productid = productid;} Public String tostring () {return "the order of this enterprise order is =" + this. enterprisename + ", the purchased product is =" + this. productid + ", order quantity =" + this. orderproductnum;} public orderapi cloneorder () {// create a new order, and then copy the data of this instance to another iseorder order = new incluiseorder (); Order. setincluisename (this. enterprisename); Order. setproductid (this. productid); Order. setorderproductnum (this. orderproductnum); return order ;}}
7.4 Business Objects for processing orders
Package demo08.prototype. example3; /*** Business Object for processing orders */public class orderbusiness {/*** method for creating orders * @ Param order interface object */Public void saveorder (orderapi order) {// according to business requirements, when the number of products in the order exceeds 1000, You need to split the order into two orders. // Of course, if you want to do well, here 1000 should be made a constant, so as to demonstrate simple // 1: determine whether the current number of pre-defined products is greater than 1000 while (Order. getorderproductnum ()> 1000) {// 2, all others are the same as orderapi neworder = order. cloneorder (); // then assign a value. The number of products is 1000neworder. setorderproductnum (1000); // 2.2 the original order is retained, and the quantity is set to reduce by 1000order. setorderproductnum (Order. getorderproductnum ()-1000); // then, the service function is processed. If it is omitted, print the output and check the system. out. println ("split to generate order =" + neworder);} // 3: no more, so you can directly process the business functions. If this parameter is omitted, print the output and check system. out. println ("Order =" + order );}}

Is this simple and refreshing?
8. prototype model thinking 8.1 explanation of prototype mode

Create a new object instance by cloning
Copy the property value of the prototype instance for the cloned object, not new, but similar to new
8.2 Call Sequence diagram of the prototype mode

 
8.3 simple clone and deep clone

Simple clone: only responsible for passing data by value
Deep cloning: In addition to cloning and copying data, it is also responsible for cloning the data of the reference type and recursive cloning of the reference type.
Java also has a clone method.
The code that reflects the deep clone is as follows (just change it)
Public orderapi cloneorder (){
// Create a new order and copy the data of this instance
Personalorder order = new personalorder ();
Order. setcustomername (this. customername );
Order. setorderproductnum (this. orderproductnum );
// For Object-type data, you need to continue calling the object cloning method during deep cloning.
Order. setproduct (product) This. Product. cloneproduct ());
Return order;
}
8.4 nature of prototype model

Clone the generated object
8.5 Advantages and Disadvantages of Prototype

Advantage: Hiding specific implementation types from the client and dynamically changing specific implementation types during runtime
Disadvantage: Each prototype subclass must implement the clone interface.

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.