Java 設計模式

Java 常見的設計模式

  • Proxy 代理模式
  • Factory 工廠模式
  • Singleton 單例模式
  • Delegate 委派模式
  • Strategy 策略模式
  • Prototype 原型模式
  • Template 模板模式
  1. 代理模式是Java最常見的一種設計模式,客戶端不是直接調用實際的對象,而是通過代理,來間接調用實際對象。代理模式可分爲兩種, 靜態代理,動態代理

    靜態代理:代碼實現:

package spring.service;

public interface ProxyService {
	
	void say();

}
package spring.service.impl;

import spring.service.ProxyService;

public class RealProxy implements ProxyService{

	private String name = "shanghai";
	@Override
	public void say() {
		System.out.println(name);
		
	}

}
package spring.service.impl;

import spring.service.ProxyService;

public class Real2Proxy implements ProxyService{

	private String name = "beijing";
	@Override
	public void say() {
		System.out.println(name);
		
	}

}
package spring.service.impl;

import spring.service.ProxyService;

public class ProxyServiceImpl implements ProxyService{

	private ProxyService service;
	
	public ProxyServiceImpl(ProxyService service){
		this.service = service;
	}
	
	@Override
	public void say() {
		service.say();
		
	}

}
package spring.controller;

import spring.service.ProxyService;
import spring.service.impl.ProxyServiceImpl;
import spring.service.impl.Real2Proxy;
import spring.service.impl.RealProxy;

public class ProxyController {
	
	public static void main(String[] args) {
		ProxyService service = new ProxyServiceImpl(new RealProxy());
		service.say();
		
		ProxyService service1 = new ProxyServiceImpl(new Real2Proxy());
		service1.say();
	}

}

動態代理:也叫JDK代理,跟靜態代理差不多,也有種叫cglib 代理

package spring.service.impl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * JDK 代理
 */
public class DynamicProxy implements InvocationHandler{
	
	private Object object;
	
	public DynamicProxy(Object object){
		this.object = object;
	}
	

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
		Object result = method.invoke(object, args);
        return result;
	}

}

cglib 代理,要導入 cglib jar,還可以用springcglib 代理

package spring.service.impl;

/**
 * cglib 代理
 * 目前類不能用final 修飾
 * 方法不能用static final 修飾
 */
public class Cglib {
	
	private String name = "java";
	
	public void say(){
		System.out.println(name);
	}

}
package spring.service.impl;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;


public class CglibProxy implements MethodInterceptor{
	
	private Object object;
	
	public CglibProxy(Object object){
		this.object = object;
	}
	
	public Object getProxyInstance(){
		//工具類
		Enhancer en = new Enhancer();
		//設置父類
		en.setSuperclass(object.getClass());
		//設置回調函數
		en.setCallback(this);
		//創建子類,(代理對象)
		return en.create();
	}
	

	@Override
	public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
		Object result = method.invoke(object, args);
        return result;
	}

}
package spring.controller;

import spring.service.impl.Cglib;
import spring.service.impl.CglibProxy;

public class ProxyController {
	
	public static void main(String[] args) {
		//靜態
//		ProxyService service = new ProxyServiceImpl(new RealProxy());
//		service.say();
//		
//		ProxyService service1 = new ProxyServiceImpl(new Real2Proxy());
//		service1.say();
		
		//JDk代理
//		DynamicProxy proxy = new DynamicProxy(new RealProxy());
//		ProxyService service = (ProxyService) Proxy.newProxyInstance(proxy.getClass().getClassLoader(), new Class[]{ProxyService.class}, proxy);
//		service.say();
		
		//cglib 代理
		Cglib cg = (Cglib) new CglibProxy(new Cglib()).getProxyInstance();
		cg.say();
		
	}

}

總結:三種代理模式各有優缺點和相應的適用範圍,主要看目標對象是否實現了接口。以Spring框架所選擇的代理模式舉例

在Spring的AOP編程中:

如果加入容器的目標對象有實現接口,用JDK代理

如果目標對象沒有實現接口,用Cglib代理

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章