国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

代理模式:代理在RPC、緩存、監(jiān)控等場(chǎng)景中的應(yīng)用

這篇具有很好參考價(jià)值的文章主要介紹了代理模式:代理在RPC、緩存、監(jiān)控等場(chǎng)景中的應(yīng)用。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前幾節(jié)已經(jīng)學(xué)過(guò)了設(shè)計(jì)模式中的創(chuàng)建型模式,重點(diǎn)學(xué)習(xí)了建造者模式和原型模式。此外創(chuàng)建型模式還包括單例模式和工廠模式。

  • 單例模式用來(lái)創(chuàng)建全局唯一的對(duì)象。
  • 工廠模式用來(lái)創(chuàng)建不同但是相關(guān)類型的對(duì)象(繼承同一父類或者接口的一組子類),由給定的參數(shù)來(lái)決定創(chuàng)建哪種類型的對(duì)象。
  • 建造者模式是用來(lái)創(chuàng)建復(fù)雜對(duì)象,可以通過(guò)設(shè)置不同的可選參數(shù),“定制化”地創(chuàng)建不同的對(duì)象。
  • 原型模式針對(duì)創(chuàng)建成本比較大的對(duì)象,利用對(duì)已有對(duì)象進(jìn)行復(fù)制的方式進(jìn)行創(chuàng)建,以達(dá)到節(jié)省創(chuàng)建時(shí)間的目的。

????????從今天起,我們開(kāi)始學(xué)習(xí)另外一種類型的設(shè)計(jì)模式:結(jié)構(gòu)型模式。其主要是解決一些類之間組合在一起的經(jīng)典結(jié)構(gòu),這些經(jīng)典模式可以解決特定的問(wèn)題。結(jié)構(gòu)型模式包括:代理模式、橋接模式、裝飾器模式適配器模式、門面模式、組合模式、享元模式。本文主要學(xué)習(xí)代理模式。

代理模式原理解析

????????代理模式原理和代碼實(shí)現(xiàn)比較簡(jiǎn)單,它在不改變?cè)碱惖那闆r下,創(chuàng)建出代理對(duì)象,以達(dá)到對(duì)原始類功能的增強(qiáng)。

? ? ? ? 我們看一個(gè)例子,例如:開(kāi)發(fā)了一個(gè)MetricsCollector類,用來(lái)收集接口請(qǐng)求的原始數(shù)據(jù),比如訪問(wèn)時(shí)間、處理時(shí)長(zhǎng)等。如果我在UserController中記錄訪問(wèn)時(shí)長(zhǎng)和處理時(shí)長(zhǎng)等信息。那么我們期初設(shè)計(jì)為如下代碼:

public class UserController {
  //...省略其他屬性和方法...
  private MetricsCollector metricsCollector; // 依賴注入

  public UserVo login(String telephone, String password) {
    long startTimestamp = System.currentTimeMillis();

    // ... 省略login邏輯...

    long endTimeStamp = System.currentTimeMillis();
    long responseTime = endTimeStamp - startTimestamp;
    RequestInfo requestInfo = new RequestInfo("login", responseTime, startTimestamp);
    metricsCollector.recordRequest(requestInfo);

    //...返回UserVo數(shù)據(jù)...
  }

  public UserVo register(String telephone, String password) {
    long startTimestamp = System.currentTimeMillis();

    // ... 省略register邏輯...

    long endTimeStamp = System.currentTimeMillis();
    long responseTime = endTimeStamp - startTimestamp;
    RequestInfo requestInfo = new RequestInfo("register", responseTime, startTimestamp);
    metricsCollector.recordRequest(requestInfo);

    //...返回UserVo數(shù)據(jù)...
  }
}

? ? ? ? 上述寫法會(huì)有一下問(wèn)題:1、第一,性能計(jì)數(shù)器框架代碼侵入到業(yè)務(wù)代碼中,跟業(yè)務(wù)代碼高度耦合。如果未來(lái)需要替換這個(gè)框架,那替換的成本會(huì)比較大。第二,收集接口請(qǐng)求的代碼跟業(yè)務(wù)代碼無(wú)關(guān),本就不應(yīng)該放到一個(gè)類中。業(yè)務(wù)類最好職責(zé)更加單一,只聚焦業(yè)務(wù)處理。

思考:能不能在將其寫成兩個(gè)controller中,然后將兩個(gè)controller進(jìn)行動(dòng)態(tài)結(jié)合,以達(dá)到上述代碼的功能。

我們可以采用代理模式進(jìn)行處理。代理類UserControllerProxy和原始類UserController實(shí)現(xiàn)相同的接口IUserController。UserController類只負(fù)責(zé)業(yè)務(wù)功能代理類UserControllerProxy負(fù)責(zé)在業(yè)務(wù)代碼執(zhí)行前后附加其他邏輯代碼,并通過(guò)委托的方式調(diào)用原始類來(lái)執(zhí)行業(yè)務(wù)代碼。具體的代碼實(shí)現(xiàn)如下所示:

public interface IUserController {
  UserVo login(String telephone, String password);
  UserVo register(String telephone, String password);
}

public class UserController implements IUserController {
  //...省略其他屬性和方法...

  @Override
  public UserVo login(String telephone, String password) {
    //...省略login邏輯...
    //...返回UserVo數(shù)據(jù)...
  }

  @Override
  public UserVo register(String telephone, String password) {
    //...省略register邏輯...
    //...返回UserVo數(shù)據(jù)...
  }
}

public class UserControllerProxy implements IUserController {
  private MetricsCollector metricsCollector;
  private UserController userController;

  public UserControllerProxy(UserController userController) {
    this.userController = userController;
    this.metricsCollector = new MetricsCollector();
  }

  @Override
  public UserVo login(String telephone, String password) {
    long startTimestamp = System.currentTimeMillis();

    // 委托
    UserVo userVo = userController.login(telephone, password);

    long endTimeStamp = System.currentTimeMillis();
    long responseTime = endTimeStamp - startTimestamp;
    RequestInfo requestInfo = new RequestInfo("login", responseTime, startTimestamp);
    metricsCollector.recordRequest(requestInfo);

    return userVo;
  }

  @Override
  public UserVo register(String telephone, String password) {
    long startTimestamp = System.currentTimeMillis();

    UserVo userVo = userController.register(telephone, password);

    long endTimeStamp = System.currentTimeMillis();
    long responseTime = endTimeStamp - startTimestamp;
    RequestInfo requestInfo = new RequestInfo("register", responseTime, startTimestamp);
    metricsCollector.recordRequest(requestInfo);

    return userVo;
  }
}

//UserControllerProxy使用舉例
//因?yàn)樵碱惡痛眍悓?shí)現(xiàn)相同的接口,是基于接口而非實(shí)現(xiàn)編程
//將UserController類對(duì)象替換為UserControllerProxy類對(duì)象,不需要改動(dòng)太多代碼
IUserController userController = new UserControllerProxy(new UserController());

參照基于接口而非實(shí)現(xiàn)編程的設(shè)計(jì)思想,將原始類對(duì)象替換為代理類對(duì)象的時(shí)候,為了讓代碼改動(dòng)盡量少,在剛剛的代理模式的代碼實(shí)現(xiàn)中,代理類和原始類需要實(shí)現(xiàn)相同的接口。但是,如果原始類并沒(méi)有定義接口,并且原始類代碼并不是我們開(kāi)發(fā)維護(hù)的(比如它來(lái)自一個(gè)第三方的類庫(kù)),我們也沒(méi)辦法直接修改原始類,給它重新定義一個(gè)接口。在這種情況下,我們?cè)撊绾螌?shí)現(xiàn)代理模式呢?一般采用繼承。

????????我們讓代理類繼承原始類,然后擴(kuò)展附加功能。原理很簡(jiǎn)單,不需要過(guò)多解釋,你直接看代碼就能明白。具體代碼如下所示:

public class UserControllerProxy extends UserController {
  private MetricsCollector metricsCollector;

  public UserControllerProxy() {
    this.metricsCollector = new MetricsCollector();
  }

  public UserVo login(String telephone, String password) {
    long startTimestamp = System.currentTimeMillis();

    UserVo userVo = super.login(telephone, password);

    long endTimeStamp = System.currentTimeMillis();
    long responseTime = endTimeStamp - startTimestamp;
    RequestInfo requestInfo = new RequestInfo("login", responseTime, startTimestamp);
    metricsCollector.recordRequest(requestInfo);

    return userVo;
  }

  public UserVo register(String telephone, String password) {
    long startTimestamp = System.currentTimeMillis();

    UserVo userVo = super.register(telephone, password);

    long endTimeStamp = System.currentTimeMillis();
    long responseTime = endTimeStamp - startTimestamp;
    RequestInfo requestInfo = new RequestInfo("register", responseTime, startTimestamp);
    metricsCollector.recordRequest(requestInfo);

    return userVo;
  }
}
//UserControllerProxy使用舉例
UserController userController = new UserControllerProxy();

不過(guò),剛剛的代碼實(shí)現(xiàn)還是有點(diǎn)問(wèn)題。一方面,我們需要在代理類中,將原始類中的所有的方法,都重新實(shí)現(xiàn)一遍,并且為每個(gè)方法都附加相似的代碼邏輯。另一方面,如果要添加的附加功能的類有不止一個(gè),我們需要針對(duì)每個(gè)類都創(chuàng)建一個(gè)代理類。

如果有50個(gè)要添加附加功能的原始類,那我們就要?jiǎng)?chuàng)建50個(gè)對(duì)應(yīng)的代理類。這會(huì)導(dǎo)致項(xiàng)目中類的個(gè)數(shù)成倍增加,增加了代碼維護(hù)成本。并且,每個(gè)代理類中的代碼都有點(diǎn)像模板式的“重復(fù)”代碼,也增加了不必要的開(kāi)發(fā)成本。那這個(gè)問(wèn)題怎么解決呢?

我們可以使用動(dòng)態(tài)代理來(lái)解決這個(gè)問(wèn)題。所謂動(dòng)態(tài)代理(Dynamic Proxy),就是我們不事先為每個(gè)原始類編寫代理類,而是在運(yùn)行的時(shí)候,動(dòng)態(tài)地創(chuàng)建原始類對(duì)應(yīng)的代理類,然后在系統(tǒng)中用代理類替換掉原始類。那如何實(shí)現(xiàn)動(dòng)態(tài)代理呢?

public class MetricsCollectorProxy {
  private MetricsCollector metricsCollector;

  public MetricsCollectorProxy() {
    this.metricsCollector = new MetricsCollector();
  }

  public Object createProxy(Object proxiedObject) {
    Class<?>[] interfaces = proxiedObject.getClass().getInterfaces();
    DynamicProxyHandler handler = new DynamicProxyHandler(proxiedObject);
    return Proxy.newProxyInstance(proxiedObject.getClass().getClassLoader(), interfaces, handler);
  }

  private class DynamicProxyHandler implements InvocationHandler {
    private Object proxiedObject;

    public DynamicProxyHandler(Object proxiedObject) {
      this.proxiedObject = proxiedObject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      long startTimestamp = System.currentTimeMillis();
      Object result = method.invoke(proxiedObject, args);
      long endTimeStamp = System.currentTimeMillis();
      long responseTime = endTimeStamp - startTimestamp;
      String apiName = proxiedObject.getClass().getName() + ":" + method.getName();
      RequestInfo requestInfo = new RequestInfo(apiName, responseTime, startTimestamp);
      metricsCollector.recordRequest(requestInfo);
      return result;
    }
  }
}

//MetricsCollectorProxy使用舉例
MetricsCollectorProxy proxy = new MetricsCollectorProxy();
IUserController userController = (IUserController) proxy.createProxy(new UserController());

?不過(guò)上述代碼的動(dòng)態(tài)代理需要有接口才行。如果是繼承的話,可以使用其他的動(dòng)態(tài)代理框架。這樣就不用像靜態(tài)代理(第二個(gè)代碼)哪有,針對(duì)每個(gè)類都產(chǎn)生代理對(duì)象。

?

業(yè)務(wù)系統(tǒng)的非功能性需求開(kāi)發(fā)

代理模式最常用的一個(gè)應(yīng)用場(chǎng)景就是,在業(yè)務(wù)系統(tǒng)中開(kāi)發(fā)一些非功能性需求,比如:監(jiān)控、統(tǒng)計(jì)、鑒權(quán)、限流、事務(wù)、冪等、日志和RPC請(qǐng)求等。我們將這些附加功能與業(yè)務(wù)功能解耦,放到代理類中統(tǒng)一處理,讓程序員只需要關(guān)注業(yè)務(wù)方面的開(kāi)發(fā)。實(shí)際上,前面舉的搜集接口請(qǐng)求信息的例子,就是這個(gè)應(yīng)用場(chǎng)景的一個(gè)典型例子。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-537332.html

到了這里,關(guān)于代理模式:代理在RPC、緩存、監(jiān)控等場(chǎng)景中的應(yīng)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 設(shè)計(jì)模式應(yīng)用場(chǎng)景

    工廠模式(Factory Pattern):使用工廠方法創(chuàng)建對(duì)象,而不是使用new直接實(shí)例化對(duì)象。 抽象工廠模式(Abstract Factory Pattern):提供一個(gè)創(chuàng)建一系列相關(guān)對(duì)象的接口,而無(wú)需指定它們的具體類。 單例模式(Singleton Pattern):限制一個(gè)類只能有一個(gè)實(shí)例并提供一個(gè)全局訪問(wèn)點(diǎn)

    2024年02月09日
    瀏覽(20)
  • 【設(shè)計(jì)模式-02】Strategy策略模式及應(yīng)用場(chǎng)景

    Java 官方文檔 Overview (Java SE 18 JDK 18) module index https://docs.oracle.com/en/java/javase/18/docs/api/index.html Java中使用到的策略模式 Comparator、comparable Comparator (Java SE 18 JDK 18) declaration: module: java.base, package: java.util, interface: Comparator https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/Compar

    2024年01月16日
    瀏覽(22)
  • 【設(shè)計(jì)模式-03】Strategy策略模式及應(yīng)用場(chǎng)景

    【設(shè)計(jì)模式-03】Strategy策略模式及應(yīng)用場(chǎng)景

    Java 官方文檔 Overview (Java SE 18 JDK 18) module index https://docs.oracle.com/en/java/javase/18/docs/api/index.html Java中使用到的策略模式 Comparator、comparable Comparator (Java SE 18 JDK 18) declaration: module: java.base, package: java.util, interface: Comparator https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/Compar

    2024年01月22日
    瀏覽(24)
  • 【設(shè)計(jì)模式】第七章:代理模式詳解及應(yīng)用案例

    【設(shè)計(jì)模式】第七章:代理模式詳解及應(yīng)用案例

    【設(shè)計(jì)模式】七大設(shè)計(jì)原則 【設(shè)計(jì)模式】第一章:?jiǎn)卫J?【設(shè)計(jì)模式】第二章:工廠模式 【設(shè)計(jì)模式】第三章:建造者模式 【設(shè)計(jì)模式】第四章:原型模式 【設(shè)計(jì)模式】第五章:適配器模式 【設(shè)計(jì)模式】第六章:裝飾器模式 【設(shè)計(jì)模式】第七章:代理模式 【設(shè)計(jì)模式

    2024年02月12日
    瀏覽(25)
  • 23種設(shè)計(jì)模式-仲裁者模式(Android應(yīng)用場(chǎng)景介紹)

    仲裁者模式 是一種行為設(shè)計(jì)模式,它允許將對(duì)象間的通信集中到一個(gè)中介對(duì)象中,以減少對(duì)象之間的耦合度。本文將通過(guò)Java語(yǔ)言實(shí)現(xiàn)仲裁者模式,并介紹如何在安卓開(kāi)發(fā)中使用該模式。 實(shí)現(xiàn)仲裁者模式 我們將使用一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明仲裁者模式的實(shí)現(xiàn),假設(shè)我們有三個(gè)類

    2023年04月14日
    瀏覽(39)
  • 23種設(shè)計(jì)模式-備忘錄模式(Android應(yīng)用場(chǎng)景介紹)

    備忘錄模式 是一種行為型設(shè)計(jì)模式,它允許在不破壞封裝性的前提下捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可以將該對(duì)象恢復(fù)到原先保存的狀態(tài)。 備忘錄模式通常包括三個(gè)角色:原發(fā)器(Originator)、備忘錄(Memento)和負(fù)責(zé)人(Caretaker)。原發(fā)

    2023年04月16日
    瀏覽(22)
  • 前端的23種設(shè)計(jì)模式及應(yīng)用場(chǎng)景

    前端的23種設(shè)計(jì)模式及應(yīng)用場(chǎng)景

    設(shè)計(jì)模式是在軟件開(kāi)發(fā)中經(jīng)過(guò)驗(yàn)證的解決問(wèn)題的方法。它們是從經(jīng)驗(yàn)中總結(jié)出來(lái)的,可以幫助我們更好地組織和管理代碼,提高代碼的可維護(hù)性、可擴(kuò)展性和可重用性。無(wú)論是前端還是后端開(kāi)發(fā),設(shè)計(jì)模式都扮演著重要的角色。在本專欄中,我們將探索一些常見(jiàn)的前端設(shè)計(jì)模

    2024年02月20日
    瀏覽(38)
  • GOF 23 種設(shè)計(jì)模式應(yīng)用場(chǎng)景分析

    本文看下GOF 23 種設(shè)計(jì)模式應(yīng)用場(chǎng)景,詳細(xì)的還是通過(guò)文章給出參考鏈接學(xué)習(xí)下。 參考這篇文章 。 有幾種產(chǎn)品需要?jiǎng)?chuàng)建,比如創(chuàng)建紅蘋果,青蘋果,綠蘋果,這些對(duì)象通過(guò)一個(gè)對(duì)象就可以。 參考這篇文章 。 有幾種產(chǎn)品需要?jiǎng)?chuàng)建,但是每種產(chǎn)品不能簡(jiǎn)單的通過(guò)一個(gè)對(duì)象來(lái)表示

    2024年02月16日
    瀏覽(28)
  • java 每種設(shè)計(jì)模式的作用,與應(yīng)用場(chǎng)景

    java 每種設(shè)計(jì)模式的作用,與應(yīng)用場(chǎng)景

    ??如果您覺(jué)得有用的話,記得給 博主點(diǎn)個(gè)贊,評(píng)論,收藏一鍵三連啊 ,寫作不易啊^ _ ^。 ??而且聽(tīng)說(shuō) 點(diǎn)贊的人每天的運(yùn)氣都不會(huì)太差 ,實(shí)在白嫖的話,那歡迎常來(lái)啊!!! Java中有23種經(jīng)典的設(shè)計(jì)模式,它們分為三個(gè)主要分類:創(chuàng)建型模式、結(jié)構(gòu)型模式和行為型模式。每種

    2024年02月07日
    瀏覽(18)
  • 【設(shè)計(jì)模式】builder 創(chuàng)建者設(shè)計(jì)模式詳解(包含電商應(yīng)用場(chǎng)景及代碼示例)

    在常見(jiàn)的設(shè)計(jì)模式中,“Builder” 通常是指一種設(shè)計(jì)模式,而不是具體的類或方法。Builder 模式是一種創(chuàng)建型設(shè)計(jì)模式,其目的是通過(guò)提供一個(gè)獨(dú)立的構(gòu)建器類來(lái)構(gòu)建一個(gè)復(fù)雜對(duì)象。 建造者模式 (Builder Pattern) 是一種創(chuàng)建型設(shè)計(jì)模式,它的主要目標(biāo)是為了將一個(gè)復(fù)雜對(duì)象的構(gòu)

    2024年01月21日
    瀏覽(22)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包