1, What is a design pattern
Design pattern is the solution to the general problems faced by software developers in the process of software development. These solutions are summarized by many software developers after a long period of experiments and errors.
Design pattern is a set of code design experience that is used repeatedly, known by most people, classified and catalogued
2, The role of design patterns
The purpose of using design module is to reuse the code, make the code easier to be understood by others and ensure the reliability of the code
3, Common design patterns
There are 23 common design models
3.1 singleton mode
Single class mode -- ensure that there is only one instance of a class
When classes are frequently created and destroyed, we use singleton mode, which can reduce the memory overhead and avoid multiple occupation of resources
Singleton mode conditions:
1. Construction method
2. Provide a static method [public] to return the created current class object
Two representations:
1. Lazy style
For example:
package com.wangxing.test1; /* * Lazy style */ public class lanhan { //Create construction method public lanhan(){} //First create the lanhan object private static lanhan obj=null; //The method of creating excessive lanhan class objects can avoid creating new objects every time and reduce the memory overhead public static lanhan getlanhanClass(){ if (obj==null) { obj=new lanhan(); } return obj; } }
2. Hungry Han style
For example:
package com.wangxing.test1; /* * Hungry Han style */ public class ehan { //Create construction method public ehan(){} //Create ehan objects in advance private static ehan obj=new ehan(); //Create a method to get the object public synchronized static ehan getehanClass(){ return obj; } }
The difference between lazy and hungry
Same point: ensure that there is only one object of the current class
On writing:
1. Construction method
2. Provide a static method [public] to return the created current class object
difference:
Writing: the object variable of the current class saved in the lazy style is initially null,
Save the object variable of the current class in the new expression, and the current class object with the initial value of new
Running speed: the lazy type is slightly worse than the hungry type.
Resource utilization: the hungry type is slightly worse than the lazy type.
3.2 factory mode
Factory pattern - there is a special Java class that acts as a factory for production objects
Conditions for using factory mode:
1. Large demand
2. Pull one hair and move the whole body
Roles in factory mode:
Factory role - production object
Abstract product object - [ abstract / interface ]
Specific products ------ [abstract class / interface class]
For example, there are all kinds of fruits on the farm and watermelon. Apples, bananas, etc
Factory role - agricultural factory
Abstract product role ---- fruit
Watermelon, apple, banana - specific products
1. First create the common function interface of the abstract product
package com.wangxing.test2; public interface ShuiGuo { void eat(); }
2. Create the class inheritance function of each specific fruit
package com.wangxing.test2; public class PingGuo implements ShuiGuo{ @Override public void eat() { System.out.println("I'm an apple. I need to wash it and eat it later!!!"); } }
package com.wangxing.test2; public class xigua implements shuiguo{ @Override public void eat() { System.out.println("I'm watermelon, cut and eat"); } }
3. The user who creates the farm selects the fruit as the system menu, and obtains the reflection object corresponding to a fruit according to the menu to create an instance object
menu.txt
Apple = com.wangxing.test2.pingguo
Watermelon = com.wangxing.test2.xigua
4. Create an agricultural factory to realize the factory mode
package com.wangxing.test2; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.HashMap; /** * * @author Administrator * */ public class NongChang { public static ShuiGuo createShuiGuo(String name){ ShuiGuo sg=null; //Read menu HashMap<String,String> menuMap=readMenu(); String className=menuMap.get(name); try{ //Create objects using reflection mechanism Class classobj=Class.forName(className); sg=(ShuiGuo)classobj.newInstance(); }catch(Exception e){ e.printStackTrace(); } return sg; } /** * Read menu */ private static HashMap<String,String> readMenu() { HashMap<String,String> menuMap=new HashMap<String,String>(); try{ BufferedReader read=new BufferedReader(new FileReader(new File("menu.txt"))); String menuitem=null; while((menuitem=read.readLine())!=null){ //Apple = com.wangxing.test2.PingGuo String menuarray[]=menuitem.split("="); menuMap.put(menuarray[0],menuarray[1]); } read.close(); }catch(Exception e){ } return menuMap; } }
5. Create test class
package com.wangxing.test2; import java.io.BufferedReader; import java.io.InputStreamReader; public class TestMain { public static void main(String[] args) throws Exception{ BufferedReader read=new BufferedReader(new InputStreamReader(System.in)); System.out.println("Please enter the desired fruit:"); String name=read.readLine(); ShuiGuo pg=NongChang.createShuiGuo(name); pg.eat(); } }
At this time, we do not need to judge the user's needs and then go to the new fruit object every time, but leave it to the factory to create an instance object to get specific things. Avoid repeated code writing.
3.3 agent mode
Proxy mode - provides a proxy for other objects to control access to this object
Buying train tickets is not necessarily at the railway station, but also at the consignment point
Agent mode is divided into static agent and dynamic agent
Static agents are divided into brother mode and parent-child mode
Disadvantages: additional business functions need to be provided to implement similar subclasses [heavy workload]
Brother mode -- two subclasses of the same interface
For example:
1. Create an interface with common functions between the railway station and the consignment point
package com.wangxing.test3; public interface SellPiao { void maiPiao(); }
2. Let the railway station and the consignment point inherit this interface
package com.wangxing.test3; public class huoCheZhan implements SellPiao{ @Override public void maiPiao() { System.out.println("I'm a train ticket. I bought a ticket at the railway station"); } }
package com.wangxing.test3; public class daiShouDian implements SellPiao{ @Override public void maiPiao() { System.out.println("I'm a sales agent. I'm buying tickets"); } }
3. Test
package com.wangxing.test3; public class Main { public static void main(String[] args) { huoCheZhan hcz=new huoCheZhan(); hcz.maiPiao(); daiShouDian dsd=new daiShouDian(); dsd.maiPiao(); } }
Parent child mode --- inheritance relationship
1. Create a parent class
package com.wangxing.test4; public class huoCheZhan { public void maipiao(){ System.out.println("This is the railway station. I'm selling tickets"); } }
2. Create a subclass to inherit the parent class and override the ticket selling method
package com.wangxing.test4; public class daiShouDian extends huoCheZhan{ public void maipiao(){ System.out.println("I'm an agent. I'm selling tickets"); } }
3. Test
package com.wangxing.test4; public class Main { public static void main(String[] args) { huoCheZhan hc=new huoCheZhan(); hc.maipiao(); daiShouDian ds=new daiShouDian(); ds.maipiao(); } }
Dynamic proxy - a java class is responsible for creating the object of the proxy class
JDK dynamic proxy -- create proxy class objects through the java.lang.reflect package Class Proxy class
[proxy class objects can only be provided for java classes that have implemented an interface]
For example:
1. Create interface
package com.wangxing.test5; public interface SellPiao { void maipiao(); }
2. Create a class that inherits the interface
package com.wangxing.test5; public class huoCheZhan implements SellPiao{ @Override public void maipiao(){ System.out.println("This is the railway station. I'm selling tickets"); } }
3. Create a dynamic proxy, get the reflection object through the class implementing the interface, so as to get the method of interface subclass inheriting the interface, and directly create a new object, but the method of interface subclass is still used
package com.wangxing.test5; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyObject implements InvocationHandler{ //Define target object private Object targetObject; public ProxyObject(Object targetObject){ this.targetObject=targetObject; } //Get proxy object public Object getProxy() { //java.lang.reflect package Class Proxy class //Classloader -- classloader ClassLoader loader=this.getClass().getClassLoader(); //Class<?> [] interfaces --- reflection object of the interface Class[] interfaces=this.targetObject.getClass().getInterfaces(); //InvocationHandler h---this return Proxy.newProxyInstance(loader, interfaces, this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(targetObject, args); } }
package com.wangxing.test5; public class Main { public static void main(String[] args) { huoCheZhan hcz=new huoCheZhan(); hcz.maipiao(); ProxyObject proxyobj=new ProxyObject(hcz); //Proxy class object SellPiao dsd=(SellPiao) proxyobj.getProxy(); dsd.maipiao(); } }
CGlib agent ---- CGlib is a third development package. You need to download and import it into the project in advance
[all java classes provide proxy class objects]
For example:
1. Create a class that requires a proxy
package com.wangxing.test6; public class huoCheZhan{ public void maipiao(){ System.out.println("This is the railway station. I'm selling tickets"); } }
2. Create and obtain proxy objects
package com.wangxing.test6; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class ProxyObject implements MethodInterceptor{ //Define target object private Object targetObject; public ProxyObject(Object targetObject){ this.targetObject=targetObject; } //Get proxy object public Object getProxy() { Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(targetObject.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object proxy, Method arg1, Object[] params, MethodProxy methodProxy) throws Throwable { return methodProxy.invokeSuper(proxy, params); } }
3. Test
package com.wangxing.test6; public class Main { public static void main(String[] args) { huoCheZhan hcz=new huoCheZhan(); ProxyObject proxyobj=new ProxyObject(hcz); //Proxy class object huoCheZhan daili=(huoCheZhan) proxyobj.getProxy(); daili.maipiao(); } }
Comparison:
1. Static proxy is to explicitly define a business implementation class and a proxy in the code, wrap the business method with the same name in the proxy class, and the user calls the wrapped business method through the proxy class;
Manually create a subclass with the same interface as the target class and wrap the target class.
2.JDK dynamic proxy calls the method of the same name of the class in the dynamically generated proxy class through the method name in the interface. [brother mode]
Through the Proxy class in the reflection package provided by jdk, dynamically create a subclass object that implements the same interface as the target class to wrap the target.
3.CGlib dynamic proxy inherits the business class. The generated dynamic proxy class is a subclass of the business class, and proxy by rewriting the business method. [parent-child mode]
Through the Enhancer class provided by CGlib, dynamically create a subclass object of the target class to wrap the target class.
Static proxy | JDK dynamic agent | CGlib dynamic proxy |
Create proxy classes manually | Dynamically generate proxy class objects | Dynamically generate proxy class objects |
The Proxy class in the reflection package provided by jdk | The Enhancer class provided by CGlib | |
Proxy objects can only be created for Java classes that implement interfaces | Create a proxy object for any Java class |