1. 程式人生 > >java23種設計模式之代理模式

java23種設計模式之代理模式

什麼是代理?

  簡單的來說就把通過第三方來完成一件事。

代理分為:

1.靜態代理     2.動態代理

1.靜態代理

 * 1.定義抽象行為的類【抽象類、介面】
 * 2.定義具體的實現類實現抽象方法
 * 3.定義代理類實現相同介面
 * 4.代理類必須具有實現類對應的引用
 * 
 * 缺點:
 * 只能代理一類物件
 * 擴張和維護難

直接上程式碼

 * 1.定義抽象行為的類【抽象類、介面】

​package com.proxy.staticsproxy;
/**
 * 靜態代理:
 * 1.定義抽象行為的類【抽象類、介面】
 * 2.定義具體的實現類實現抽象方法
 * 3.定義代理類實現相同介面
 * 4.代理類必須具有實現類對應的引用
 * 
 * 缺點:
 * 只能代理一類物件
 * 擴張和維護難
 * @author zy
 *
 */
public interface IFunction {
   void click();
   String getName();
}​

 * 2.定義具體的實現類實現抽象方法

package com.proxy.staticsproxy;

public class Button implements IFunction {
	
    private String name;

	public Button(String name) {
       this.name=name;
    }
	@Override
	public void click() {
		System.out.println(this.name+"被點選了");

	}

	@Override
	public String getName() {
		return name;
	}

}

* 3.定義代理類實現相同介面* 4.代理類必須具有實現類對應的引用

package com.proxy.staticsproxy;

public class StaticsProxy implements IFunction {

	private IFunction iFunction;
	private String userName;

	public StaticsProxy(IFunction iFunction,String userName) {
		this.iFunction=iFunction;
		this.userName=userName;
	}
	/*
	 * 對click進行包裝,有點像裝飾者
	 */
	@Override
	public void click() {
	   if(this.userName.equalsIgnoreCase("管理員")){
		   iFunction.click();
	   }else {
		System.out.println("沒有許可權點選");
	}

	}
//不需要的則不用管,這也是一個缺點,哪怕不用也要重寫
	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return null;
	}

}

測試類

package com.proxy.staticsproxy;

public class Test {
		public static void main(String[] args) {
			System.out.println("===========不用代理====================");
			IFunction iFunction=new Button("提交");
			iFunction.click();
			System.out.println("===========用代理====================");
			StaticsProxy staticsProxy=new StaticsProxy(iFunction, "管理員1");
			staticsProxy.click();
		}
}

2.動態代理

  * 動態代理:
 * 可以實現不同介面的代理
 * 
 * 缺點:
 * 代理的類必須實現了介面
 * 
 * spring框架的動態代理已經解決了該問題

1.定義抽象部分的介面

package com.proxy.dynamicproxy;
/**
 * 動態代理:
 * 可以實現不同介面的代理
 * 
 * 缺點:
 * 代理的類必須實現了介面
 * 
 * spring框架的動態代理已經解決了該問題
 * @author zy
 *
 */
public interface IFunction {
     void click();
     String name();
}

 2.定義實現類

package com.proxy.dynamicproxy;
/**
 * 文字框實現類
 * @author zy
 *
 */
public class Text implements IFunction {

	private String name;

	public Text(String name) {
		this.name=name;
	}
	@Override
	public void click() {
		System.out.println(this.name+"被點選了");

	}

	@Override
	public String name() {
		return name;
	}

}

 3.定義動態代理類

package com.proxy.dynamicproxy;

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

public class DynamicProxy {
	//定義object的物件,所以類的父類都是object
	private Object obj;
	private String userName;
   public DynamicProxy() {
     }
   //初始化
	public DynamicProxy(Object obj,String userName) {
		this.obj=obj;
		this.userName=userName;
	}
	//建立動態代理的物件;使用jdk自帶的proxy來建立
	public  Object createProxy(){
	return	Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),new HanderProxy());
	}
	
	//定義執行處理內部類
	private class HanderProxy implements InvocationHandler{

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			Object invoke=null;
			//判斷該引用是否是car型別
			if(!(obj instanceof Car)){
				validateLogin();
				validateRole();
				//這是是獲取該方法執行後的返回值
				invoke=method.invoke(obj,args);
				requestDB();
				responseWeb();
			}else {
				 invoke = method.invoke(obj,args);
				 System.out.println(invoke);
			}
			
			return invoke;
		}
	}
   
	private void validateLogin(){
		System.out.println("登陸驗證通過");
	}
	private void validateRole(){
		System.out.println(this.userName+"身份驗證通過");
	}
	private void requestDB(){
		System.out.println("請求資料庫");
	}
	private void responseWeb(){
		System.out.println("響應到頁面");
	}
}

4.測試類

package com.proxy.dynamicproxy;

public class Test {
	public static void main(String[] args) {
		IFunction iFunction=new Text("文字框");
		DynamicProxy dynamicProxy=new DynamicProxy(iFunction, "管理員");
		IFunction proxy =(IFunction)dynamicProxy.createProxy();
		proxy.click();
		System.out.println("=============================");
		//另一個介面
		Car car=new Bike();
		car.setName("山地自行車");
		 dynamicProxy=new DynamicProxy(car, "管理員");
		 Car car2 =(Car)dynamicProxy.createProxy();
		 car2.numberOfWheel();
		 car2.getName();
	}
}

還有一個介面我並沒有釋出出來,第一次學習代理的可以自己試著寫一寫,畢竟自己寫出來的才是自己的 

執行結果: 

登陸驗證通過
管理員身份驗證通過
文字框被點選了
請求資料庫
響應到頁面
=============================
自行車有兩個輪子
null
山地自行車