代理模式是23種設計模式中結構型模式的一種,它的核心是通過代理類來完成其他對象的訪問,降低訪問者和被訪問者的耦合度,也對功能進行了增強。 ...
前言
本文主要講述代理模式,文中使用通俗易懂的案例,使你更好的學習本章知識點並理解原理,做到有道無術。
一.什麼是代理模式
代理模式是23種設計模式中結構型模式的一種,它的核心是通過代理類來完成其他對象的訪問,降低訪問者和被訪問者的耦合度,也對功能進行了增強。
二.生活中的代理模式
1.經紀人
每個藝人都擁有自己的經紀人,幫助他處理工作上的事情,例如幫藝人接活、商務談判、宣傳包裝等等,如果我們想聯繫上哪位藝人,主要就是通過經紀人來完成,而經紀人就跟設計模式中的代理模式類似。
2.房產中介
現在很多年輕人在大城市工作都是租房住的,大家現在購買房子或者租房的話是不是通過房產中介呢,反正是通過房產中介找到房子的,而房產中介他是負責幫助房主出售或者出租房子的,通過房產中介我們就無需每個房子都需要通過聯繫房主來獲取房源信息,大大提高了我們選房效率,而房產中介就跟設計模式中的代理模式類似。
3.婚介
現在有很多婚介公司或者各種APP來幫助大家擴展社交範圍,認識更多的人,提升戀愛率和結婚率。而婚介公司或者各種交友APP就跟設計模式中的代理模式類似。
三.代理模式的實現
代理模式有兩種,一種是靜態代理,一種是動態代理
1.靜態代理
接下來就以演員和經紀人來舉例,通過靜態代理來實現。先創建一個介面和被代理對象類演員類以及靜態代理類經紀人類
package com.qianfeng.ran;
/*
* @author:江帥
* 介面
* 人類介面
*/
public interface Human {
void behavior();
}
/*
* @author:江帥
* 被代理對象類
* 演員類
*/
class Actor implements Human{
@Override
public void behavior() {
System.out.println("某某明星進行拍戲");
}
}
/*
* @author:江帥
* 靜態代理類
* 經紀人
*/
class Broker implements Human{
private Human human;
//獲取具體的明星對象
public Broker(Human human){
this.human = human;
}
@Override
public void behavior() {
System.out.println("接商演");
System.out.println("安排行程");
human.behavior();
System.out.println("後續工作進行");
}
}
然後創建一個客戶端使用代理模式,完成通過經紀人聯繫演員讓演員拍戲,並增強功能
package com.qianfeng.ran;
/*
* @author:江帥
* 客戶端
*/
public class Demo {
public static void main(String[] args) {
//創建明星對象
Actor actor = new Actor();
//創建經紀人對象並傳遞明星對象
Broker broker = new Broker(actor);
//執行結果:
//接商演
//安排行程
//某某明星進行拍戲
//後續工作進行
broker.behavior();
}
}
2.動態代理
接下來我們以房產中介的來舉例,使用動態代理來實現。先創建代理介面人類介面和被代理對象類用戶類
package com.qianfeng.ran;
/*
* @author:江帥
* 介面
* 人類介面
*/
public interface Human {
void behavior();
}
/*
* @author:江帥
* 被代理對象類
* 用戶
*/
public class User implements Human{
@Override
public void behavior() {
System.out.println("租房");
}
}
再創建一個動態代理類房產中介類
package com.qianfeng.ran;
/*
* @author:江帥
* 動態代理類
* 房產中介
*/
public class DynamicProxy implements InvocationHandler {
//需要被代理的對象
private Object obj;
public Object newInstance(Object obj){
this.obj = obj;
/**
* 第一個參數為被代理對象的類載入器
* 第二個參數為被代理對象的介面
* 第三個此參數為當前對象
*/
return Proxy.newProxyInstance(obj.getClass().getClassLoader()
,obj.getClass().getInterfaces(),
this);
}
/**
* 調用被代理對象的方法都會經過該方法
* @param proxy 代理對象的引用
* @param method 被調用的方法對象
* @param args 被調用方法的參數數組
* @return 原方法的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
start();
//調用被代理對象的方法
Object respBean = method.invoke(obj, args);
commit();
return respBean;
}
public void start(){
System.out.println("帶客戶看房子");
}
public void commit(){
System.out.println("與客戶簽署合同");
}
}
最後動態代理實現通過房產中介增強用戶尋找房子的行為
package com.qianfeng.ran;
/*
* @author:江帥
* 客戶端
*/
public class Demo {
public static void main(String[] args) {
//創建房產中介 -- 代理對象類
DynamicProxy proxy = new DynamicProxy();
//通過房產中介找房子 -- 調用代理對象的方法並傳遞被代理對象,實現增強
Human human = (Human) proxy.newInstance(new User());
//執行結果:
//帶客戶看房子
//租房
//與客戶簽署合同
human.behavior();
}
}
五.總結
代理模式中分為兩種代理:靜態代理和動態代理
靜態代理的實現會導致代理類的冗餘,每增加一個被代理對象就需要增加一個代理類。就像一對一的明星經紀人,每多一個明星就需要多一個經紀人。
動態代理的實現則減少了代理類的冗餘,只需要一個動態代理類即可,但是會對被代理的對象每個方法都進行增強。就像房產中介,每多個客戶並不需要再額外多一個中介來服務,房產中介可以一個人對多個用戶,但是每個用戶得到的都是同一個房產中介的服務。
下一章,將帶大家學習電腦與游戲的關係(設計模式之橋接模式)