Practical application of design mode 5: Factory method mode

Source: Internet
Author: User
Definition of factory method mode
The factory method model is widely used. The factory method mode is widely used in Java APIs: Java. util. the iterator method of the collection interface is an example of a well-known Abstract Factory method; java.net. createurlstreamhandler (string protocol) of urlstreamhandlerfactory is also a classic application of the factory method mode. urlstreamhandlerfactory defines a createurlstreamhandler method used to create urlstreamhandler instances. How to create it? The specific implementation class has the final say; in addition, the factory method mode application examples in Java API include java.net. contenthandlerfactory and java.net. url openconnection method .......
Gof classifies the factory method pattern into the object creation pattern, and defines the factory method pattern clearly in design pattern: Basis for reusable object-oriented software: "define an interface for creating an object, but let subclasses decide which class to instantiate. factory method lets a class defer Instantiation to subclasses. "translation :" Defines an interface for creating an object, but leaves the instance of the specific class to the subclass. The factory method allows initialization of a class to be delayed to its own subclass."
Why factory method mode?
By using the factory method to create an object, we can avoid the client code relying on the specific implementation of the interface it uses. The client no longer needs to inject the constructor of object creation into its own code. The client only needs to call the factory to determine the creation process of child classes that meet the requirements. In addition, the factory method can meet the needs of constructing different objects each time, complex object structures, and Object Structures dependent on specific environments.
Use Cases of factory method mode
  • The client does not know which subclass it is to create.
  • A class wants its own subclass to define the creation process of an object.
  • Class will create a responsibility proxy for an object to one of the help subclass, and you want to localize which subclass as the proxy information.
Factory method mode vs simple factory Mode
  • Simple factory, also known as "static factory", is the biggest difference between the factory method and the simple factory, which is also the feature of the two modes that are most likely to be separated.
  • Although both of them are partial encapsulation of object creation, a simple factory focuses on code reuse of object creation, reuse of created instances, or uniformity of instance creation; the factory method focuses on the implementation of the specific creation logic of child classes.
  • In the simple factory mode, the factory class is the core of product class instantiation, and the factory method mode hands over the initialization work to the subclass implementation. In other words, if a new product is added, the simple factory needs to modify its own factory class, while the factory method only needs to add a new factory subclass-the simple factory does not support the OCP principle as well as the factory method.
Java Web application calls C ++ encryption and decryption Methods
As we all know, Java's file encryption and decryption efficiency is not as good as the underlying C/C ++. To improve program performance, we need to use Java for JNI to call the underlying encryption and decryption methods.
Analysis of Java Web application Calling C ++ encryption and decryption Methods
Since underlying calls are involved, cross-platform applications should be considered. In addition, applications must support at least Linux and Windows, and may be deployed on Mac in the future. These platforms are also divided into 64-bit and 32-bit. Therefore, we need to prepare an underlying encryption/Decryption library for each platform. because the number of digits of the underlying database is not compatible, there must be two databases under each platform: 32-bit and 64-bit.
Each database should have corresponding classes for loading, such as COM. defonds. cloud. tool. config. encrypt. encryptorlinuxamd64.java, which is called the encryption and decryption class. After this class is written, use shell to generate the com_defonds_cloud_tool_config_encrypt_encryptorlinuxamd64.h header file. C/C ++ programmers encapsulate the encryption Library.
The encryption/Decryption class is instantiated and managed in the factory mode.
Java Web application Calling C ++ encryption and decryption method design

Java Web application Calling C ++ encryption and decryption method source code
Client class encryptorutil source code:
package com.defonds.cloud.tool.config.util;import com.defonds.cloud.tool.config.encrypt.Encryptor;import com.defonds.cloud.tool.config.encrypt.factory.EncryptorFactory;import com.defonds.cloud.tool.config.encrypt.factory.EncryptorFactoryLinux;import com.defonds.cloud.tool.config.encrypt.factory.EncryptorFactoryMac;import com.defonds.cloud.tool.config.encrypt.factory.EncryptorFactoryWindows;public class EncryptorUtil {private static String osName = System.getProperties().getProperty("os.name");private static Encryptor encryptor;static {EncryptorFactory encryptorFactory;if (osName.equals("Linux")) { // os is linuxencryptorFactory = new EncryptorFactoryLinux();} else if (osName.contains("Windows")) { // os is windowsencryptorFactory = new EncryptorFactoryWindows();} else { // os is macencryptorFactory = new EncryptorFactoryMac();}encryptor = encryptorFactory.getEncryptor();}/** *  * @param content - the string to be encrypt or decrypt * @param flag - encrypt flag, true is encrypt, false is decrypt * @return - string after encrypt or decrypt */public static String encryptorStr(String content, boolean flag) {return EncryptorUtil.encryptor.encrypt(content, flag);}}

Product encryptor interface:
package com.defonds.cloud.tool.config.encrypt;public interface Encryptor {/** * @param content str to be encrypted * @param flag true:encrypt false:decrypt * @return */public String encrypt(String content, boolean flag);}

One of the specific product categories is encryptorlinuxamd64 source code (according to the libaesjni written by encryptorlinuxamd64. the so library is already in the/COM/defonds/cloud/tool/config/encrypt/native/Linux/amd64 directory under classpath ):
package com.defonds.cloud.tool.config.encrypt;import java.io.IOException;import com.defonds.cloud.tool.config.util.NativeUtils;public class EncryptorLinuxAmd64 implements Encryptor {// Native method declaration    // use the keyword "native" indicate this is an ‘unsafe‘ mtehod for java    native String encryptStr(String content, boolean flag);        // Load the library    static {        try {    System.loadLibrary("libaesjni");    }catch (UnsatisfiedLinkError e) {            try {NativeUtils.loadLibraryFromJar("/com/defonds/cloud/tool/config/encrypt/native/linux/amd64/libaesjni.so");} catch (IOException e1) {throw new RuntimeException(e1);} // during runtime. .DLL within .JAR    }    }@Overridepublic String encrypt(String content, boolean flag) {// TODO Auto-generated method stubreturn this.encryptStr(content, flag);}}

Factory interface encryptorfactory:
package com.defonds.cloud.tool.config.encrypt.factory;import com.defonds.cloud.tool.config.encrypt.Encryptor;public interface EncryptorFactory {public Encryptor getEncryptor();}

One of the specific factory classes is encryptorfactorylinux source code:
package com.defonds.cloud.tool.config.encrypt.factory;import com.defonds.cloud.tool.config.encrypt.Encryptor;import com.defonds.cloud.tool.config.encrypt.EncryptorLinuxAmd64;import com.defonds.cloud.tool.config.encrypt.EncryptorLinuxI386;public class EncryptorFactoryLinux implements EncryptorFactory {private static String osArch = System.getProperties().getProperty("os.arch");@Overridepublic Encryptor getEncryptor() {if (osArch.equals("amd64")) { // os is linux amd64return new EncryptorLinuxAmd64();} else { // os is linux i386return new EncryptorLinuxI386();}}}

Java Web application calls the C ++ encryption and decryption method to test
The test code is as follows:
String abc = "abc";System.out.println("before encrypt:" + abc);String abcEncrypted = EncryptorUtil.encryptorStr(abc, true);System.out.println("after encrypt:" + abcEncrypted);String abc2 = EncryptorUtil.encryptorStr(abcEncrypted, false);System.out.println("after decrypt:" + abc2);

Running result:
Before encrypt: ABC
After encrypt: 3a5dd7db74fdab404e980805b1998e81
After decrypt: ABC
Postscript 1
Readers may find that Java Web application calls the C ++ encryption and decryption method can be fully implemented in a simple factory mode, and even the effect may be better (because you don't need to add new factory objects every time):
public class EncryptorFactory {private static Properties sp = System.getProperties(); private static String osName = sp.getProperty("os.name");private static String osArch = sp.getProperty("os.arch");private static int index2 = osName.indexOf("indows");private static boolean isWindows = false;static {if (index2 != -1) {isWindows = true;}     }public static Encryptor getEncryptor() {if (isWindows) { // os is windowsif (osArch.equals("amd64")) { // os is windows amd64return new EncryptorWindowsAmd64();} else { // os is windows x86return new EncryptorWindowsX86();}} else { // os is linuxif (osArch.equals("amd64")) { // os is linux amd64return new EncryptorLinuxAmd64();} else { // os is linux i386return new EncryptorLinuxI386();}}}}

Originally, a simple factory is a special case of a factory method. gof did not even describe it in 23 design models, and many documents do not have the concept of a simple factory. So when will simple factories be used? I suggest, If you can predict the situation of all products, use a simple factory. Otherwise, use the factory method..
Postscript 2
When running JNI, if an error similar to Java. Lang. unsatisfiedlinkerror:/tmp/character: wrong Elf class: elfclass32 (possible cause: Architecture word width mismatch) occurs:
Exception in thread "Main" Java. Lang. unsatisfiedlinkerror:/tmp/keys: wrong Elf class: elfclass32 (possible cause: Architecture word width mismatch)
At java. Lang. classloader $ nativelibrary. Load (native method)
At java. Lang. classloader. loadlibrary0 (classloader. Java: 1747)
At java. Lang. classloader. loadlibrary (classloader. Java: 1643)
At java. Lang. runtime. load0 (runtime. Java: 787)
At java. Lang. system. Load (system. Java: 1022)
At com. defonds. Cloud. tool. config. util. nativeutils. loadlibraryfromjar (nativeutils. Java: 91)
At com. defonds. Cloud. tool. config. encrypt. encryptorlinux. <clinit> (encryptorlinux. Java: 20)
At com. defonds. Cloud. tool. config. util. encryptorfactory. getencryptor (encryptorfactory. Java: 24)
At com. defonds. Cloud. tool. config. configutil. <clinit> (configutil. Java: 7)
At testtime. Main (testtime. Java: 26)
Solution: Provide 64-bit and 32-bit libraries respectively.
Postscript 3
If JNI encounters the following error:
Java: Symbol lookup error:/tmp/libaesjni4570314921835538044.so: Undefined Symbol: aesrun
Java: Symbol lookup error:/tmp/libaesjni8667398299924425273.so: Undefined Symbol: getstringutfchars
Solution: this is because C ++ calls C functions and the compilation rules are different. replace all c ++ code (CPP suffix) with C code and recompile it.
References
  • C ++ and Java Mixed Programming

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.