日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Nacos竟然是這樣使用代理模式的?

本文轉(zhuǎn)載自微信公眾號(hào)「程序新視界」,作者丑胖俠二師兄 。轉(zhuǎn)載本文請(qǐng)聯(lián)系程序新視界公眾號(hào)。

創(chuàng)新互聯(lián)公司是一家專(zhuān)注于網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站建設(shè)與策劃設(shè)計(jì),南木林網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:南木林等地區(qū)。南木林做網(wǎng)站價(jià)格咨詢:18982081108

學(xué)習(xí)不用那么功利,二師兄帶你從更高維度輕松閱讀源碼~

隨著對(duì)Nacos源碼的深入閱讀,感覺(jué)越來(lái)越有意思了,大量的設(shè)計(jì)模式和基礎(chǔ)知識(shí)點(diǎn)都在其中被運(yùn)用。不論你是否閱讀源碼,都值得借鑒一下Nacos的運(yùn)用案例。

今天這篇文章,給大家介紹一下Nacos Client中對(duì)代理模式的運(yùn)用。閱讀這篇文章,你可以不懂Nacos源碼,但能夠?qū)W到代理模式的運(yùn)用;如果你準(zhǔn)備閱讀Nacos源碼,不僅可以學(xué)到代理模式的案例,還可以更加深刻的感知到Nacos中的設(shè)計(jì)思想。

代理模式簡(jiǎn)介

通俗的來(lái)講,代理模式就是讓別人(代理)幫忙做你并不關(guān)心的事,作用就相當(dāng)于日常生活中的中介。

比如,日常生活中,你想買(mǎi)輛車(chē),你可以直接去自己挑選、質(zhì)檢等,但這個(gè)過(guò)程會(huì)耗費(fèi)你大量的時(shí)間和精力。那么,此時(shí)你就可以找一個(gè)代理,來(lái)幫忙實(shí)現(xiàn)挑選、質(zhì)檢的事情。

對(duì)于軟件設(shè)計(jì)來(lái)說(shuō),代理模式的定義為:代理模式給某一個(gè)對(duì)象提供一個(gè)代理對(duì)象,并由代理對(duì)象控制對(duì)原對(duì)象的引用。通俗的來(lái)講代理模式就是我們生活中常見(jiàn)的中介。

代理模式的結(jié)構(gòu)

在不使用代理模式時(shí),我們大概是這樣使用一個(gè)接口:圖片

客戶端在使用CarService接口時(shí)需要?jiǎng)?chuàng)建CarServiceImpl類(lèi)的實(shí)例,然后進(jìn)行業(yè)務(wù)邏輯處理。

但在某些場(chǎng)景下,一個(gè)客戶類(lèi)不想或者不能直接引用一個(gè)委托對(duì)象(CarServiceImpl),此時(shí)代理類(lèi)對(duì)象可以在客戶類(lèi)和委托對(duì)象之間起到中介的作用,并提供相同的功能。

如果提供相同的功能,那么代理類(lèi)和委托類(lèi)就需要實(shí)現(xiàn)相同的接口。此時(shí),上圖就演變成了代理模式:

代理模式

在代理模式的圖中,對(duì)比普通的直接使用,新增了代理類(lèi),并且代理類(lèi)持有了委托類(lèi)(真實(shí)對(duì)象)的引用。代理類(lèi)本身并不真正實(shí)現(xiàn)服務(wù),而是通過(guò)調(diào)用委托類(lèi)的相關(guān)方法,來(lái)提供特定的服務(wù),所以要持有真實(shí)類(lèi)的引用。

代理類(lèi)可以在業(yè)務(wù)功能執(zhí)行的前后加入一些公共的服務(wù),比如負(fù)責(zé)為委托類(lèi)預(yù)處理消息、過(guò)濾消息、把消息轉(zhuǎn)發(fā)給委托類(lèi),以及事后對(duì)返回結(jié)果的處理等。

代理模式中的角色:

  • 抽象主題類(lèi)(Subject):聲明了目標(biāo)對(duì)象和代理對(duì)象的共同接口,在任何可以使用目標(biāo)對(duì)象的地方都可以使用代理對(duì)象。
  • 具體主題類(lèi)(RealSubject):也稱(chēng)為委托角色或者被代理角色。定義了代理對(duì)象所代表的目標(biāo)對(duì)象。
  • 代理類(lèi)(Proxy):也叫委托類(lèi)、代理類(lèi)。代理對(duì)象內(nèi)部含有目標(biāo)對(duì)象的引用,從而可以在任何時(shí)候操作目標(biāo)對(duì)象;代理對(duì)象提供一個(gè)與目標(biāo)對(duì)象相同的接口,以便可以在任何時(shí)候替代目標(biāo)對(duì)象。代理對(duì)象通常在客戶端調(diào)用傳遞給目標(biāo)對(duì)象之前或之后,執(zhí)行某個(gè)操作,而不是單純地將調(diào)用傳遞給目標(biāo)對(duì)象。

代理模式實(shí)現(xiàn)

以上面的結(jié)構(gòu)圖為例,來(lái)看看代理模式的代碼實(shí)現(xiàn)。

定義抽象主題類(lèi)(CarService)、具體主題類(lèi)(CarServiceImpl)、代理類(lèi)(CarServiceProxy):

 
 
 
 
  1. // 抽象主題類(lèi) 
  2. public interface CarService { 
  3.     // 選車(chē) 
  4.     Car chooseCar(); 
  5.     // 質(zhì)量檢查 
  6.     boolean qualityCheck(); 
  7.  
  8. // 具體主題類(lèi) 
  9. public class CarServiceImpl implements CarService { 
  10.     @Override 
  11.     public Car chooseCar() { 
  12.         System.out.println("真實(shí)操作:選車(chē)"); 
  13.         return new Car(); 
  14.     } 
  15.  
  16.     @Override 
  17.     public boolean qualityCheck() { 
  18.         System.out.println("真實(shí)操作:質(zhì)量檢測(cè)"); 
  19.         return true; 
  20.     } 
  21.  
  22. // 代理類(lèi) 
  23. public class CarServiceProxy implements CarService { 
  24.  
  25.     private CarServiceImpl real; 
  26.  
  27.     public CarServiceProxy() { 
  28.         real = new CarServiceImpl(); 
  29.     } 
  30.  
  31.     @Override 
  32.     public Car chooseCar() { 
  33.         System.out.println("代理類(lèi)CarServiceProxy選車(chē):先添加一些日志"); 
  34.         return real.chooseCar(); 
  35.     } 
  36.  
  37.     @Override 
  38.     public boolean qualityCheck() { 
  39.         System.out.println("代理類(lèi)CarServiceProxy質(zhì)量檢測(cè):先添加一些日志"); 
  40.         return real.qualityCheck(); 
  41.     } 

對(duì)應(yīng)的客戶端測(cè)試類(lèi):

 
 
 
 
  1. public class Client { 
  2.  
  3.     public static void main(String[] args) { 
  4.  
  5.         CarService carService = new CarServiceProxy(); 
  6.         carService.chooseCar(); 
  7.         carService.qualityCheck(); 
  8.     } 

直接使用代理類(lèi),就可以完成預(yù)期的工作。

執(zhí)行程序,打印日志如下:

  • 代理類(lèi)CarServiceProxy選車(chē):先添加一些日志
  • 真實(shí)操作:選車(chē)
  • 代理類(lèi)CarServiceProxy質(zhì)量檢測(cè):先添加一些日志
  • 真實(shí)操作:質(zhì)量檢測(cè)

可以看出,在真實(shí)的操作之前,可以通過(guò)代理類(lèi)添加一些其他的操作。

Nacos的代理模式實(shí)踐

上面了解了代理模式的基本知識(shí)以及實(shí)例,下面就來(lái)看看Nacos中是如何實(shí)現(xiàn)代理模式的。

Nacos Client與注冊(cè)中心進(jìn)行通信采用了兩種通信協(xié)議:HTTP協(xié)議和gRPC協(xié)議。這兩個(gè)協(xié)議實(shí)現(xiàn)了共同的抽象主題類(lèi)NamingClientProxy,具體主題類(lèi)有NamingHttpClientProxy和NamingGrpcClientProxy,分別對(duì)應(yīng)Http協(xié)議和gRPC協(xié)議實(shí)現(xiàn)。

此時(shí),Nacos考慮到要支持通過(guò)配置來(lái)靈活選擇具體的通信協(xié)議,而這個(gè)功能呢又沒(méi)辦法讓這兩個(gè)具體的主題類(lèi)來(lái)實(shí)現(xiàn),因此就產(chǎn)生了一個(gè)代理類(lèi)NamingClientProxyDelegate來(lái)完成一些預(yù)先的處理和判斷。

整個(gè)代理模式的使用類(lèi)圖如下:

代理模式

通過(guò)上圖可以發(fā)現(xiàn),Nacos的代理模式使用與標(biāo)準(zhǔn)的代理模式還有一些區(qū)別。

首先,NamingClientProxyDelegate同時(shí)代理了具體主題類(lèi),這可能考慮的是方便通信協(xié)議的配置切換。同時(shí),在代理類(lèi)中還處理了一些事件監(jiān)聽(tīng)等額外功能。

其次,說(shuō)話Nacos這塊的命名并不友好,比如抽象主題直接以Proxy為后綴,容易讓人混淆。這就導(dǎo)致與代理模式中的代理類(lèi)命名沖突,于是將代理類(lèi)的后綴替換為了Delegate。

上圖中的客戶類(lèi)便是NacosNamingService,在其中實(shí)現(xiàn)了代理類(lèi)的初始化操作,具體代碼實(shí)現(xiàn)如下:

 
 
 
 
  1. public class NacosNamingService implements NamingService { 
  2.     // ... 
  3.     private NamingClientProxy clientProxy; 
  4.    
  5.     private void init(Properties properties) throws NacosException { 
  6.         // ... 
  7.         this.clientProxy = new NamingClientProxyDelegate(this.namespace, serviceInfoHolder, properties, changeNotifier); 
  8.     } 
  9.      
  10.     @Override 
  11.     public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException { 
  12.         NamingUtils.checkInstanceIsLegal(instance); 
  13.         clientProxy.registerService(serviceName, groupName, instance); 
  14.     } 
  15.     // ... 
  16. }   

抽象主題類(lèi)NamingClientProxy為接口,部分代碼如下:

 
 
 
 
  1. public interface NamingClientProxy extends Closeable { 
  2.      
  3.     void registerService(String serviceName, String groupName, Instance instance) throws NacosException; 
  4.   
  5.     void deregisterService(String serviceName, String groupName, Instance instance) throws NacosException; 
  6.     
  7.    // ... 

代理類(lèi)NamingClientProxyDelegate部分實(shí)現(xiàn)如下:

 
 
 
 
  1. public class NamingClientProxyDelegate implements NamingClientProxy { 
  2.     // ... 
  3.     private final NamingHttpClientProxy httpClientProxy; 
  4.      
  5.     private final NamingGrpcClientProxy grpcClientProxy; 
  6.      
  7.     public NamingClientProxyDelegate(String namespace, ServiceInfoHolder serviceInfoHolder, Properties properties, 
  8.             InstancesChangeNotifier changeNotifier) throws NacosException { 
  9.          // ...        
  10.         this.httpClientProxy = new NamingHttpClientProxy(namespace, securityProxy, serverListManager, properties, 
  11.                 serviceInfoHolder); 
  12.         this.grpcClientProxy = new NamingGrpcClientProxy(namespace, securityProxy, serverListManager, properties, 
  13.                 serviceInfoHolder); 
  14.     } 
  15.   // ... 

可以看出,代理類(lèi)實(shí)現(xiàn)了NamingClientProxy接口,同時(shí)持有了NamingHttpClientProxy和NamingGrpcClientProxy的對(duì)象引用,并且對(duì)它們進(jìn)行了初始化操作。

關(guān)于NamingHttpClientProxy和NamingGrpcClientProxy的代碼我們就不再展示,它們首先繼承了AbstractNamingClientProxy抽象類(lèi),該抽象類(lèi)實(shí)現(xiàn)NamingClientProxy接口。

從整體上來(lái)說(shuō),Nacos中對(duì)代理模式的運(yùn)用還是比較靈的,結(jié)合場(chǎng)景一個(gè)代理類(lèi)代理了兩個(gè)具體實(shí)現(xiàn)類(lèi),但同時(shí)在命名方面的問(wèn)題,還有待商榷。

代理模式和裝飾器模式的區(qū)別

在學(xué)習(xí)使用代理模式時(shí),經(jīng)常會(huì)有朋友與裝飾器模式相混淆。這里就簡(jiǎn)單聊一下它們直接的區(qū)別。

裝飾器模式中,裝飾者(decorator)和被裝飾者(decoratee)都實(shí)現(xiàn)同一個(gè)接口。代理模式中,代理類(lèi)(proxy class)和真實(shí)處理的類(lèi)(real class)都實(shí)現(xiàn)同一個(gè)接口。而且兩者都對(duì)類(lèi)的方法進(jìn)行擴(kuò)展,看起來(lái)邊界的確比較模糊。

但還是有一些區(qū)別點(diǎn)的:

  • 裝飾器模式強(qiáng)調(diào)的是增強(qiáng)自身,比如增加之后可提供更多的屬性和方法;代理模式強(qiáng)調(diào)要讓別人幫你去做一些本身與你業(yè)務(wù)沒(méi)有太多關(guān)系的職責(zé)(記錄日志、設(shè)置緩存)。代理模式是為了實(shí)現(xiàn)對(duì)象的控制,因?yàn)楸淮淼膶?duì)象往往難以直接獲得或者是其內(nèi)部不想暴露出來(lái)。
  • 裝飾模式是以對(duì)客戶端透明的方式擴(kuò)展對(duì)象的功能,是繼承方案的一個(gè)替代方案;代理模式則是給一個(gè)對(duì)象提供一個(gè)代理對(duì)象,并由代理對(duì)象來(lái)控制對(duì)原有對(duì)象的引用;
  • 裝飾模式是為裝飾的對(duì)象增強(qiáng)功能;而代理模式對(duì)代理的對(duì)象施加控制,但不對(duì)對(duì)象本身的功能進(jìn)行增強(qiáng);

小結(jié)

 

代理模式在日常業(yè)務(wù)代碼中還是比較少見(jiàn)的,本文我們重點(diǎn)介紹了靜態(tài)代理模式及在Nacos中的運(yùn)用。關(guān)于動(dòng)態(tài)代理,在Spring的框架中可以看到很多實(shí)例,有機(jī)會(huì)我們?cè)龠M(jìn)行講解。而Nacos中對(duì)代理模式的運(yùn)用算是比較靈活,同時(shí)也并不是那么完美。這或許也提供了我們對(duì)代理模式認(rèn)知的另外一個(gè)視角。


網(wǎng)頁(yè)題目:Nacos竟然是這樣使用代理模式的?
路徑分享:http://www.5511xx.com/article/cdjhceo.html