色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

裝飾器模式和代理模式的區別

科技綠洲 ? 來源:Java技術指北 ? 作者:Java技術指北 ? 2023-10-08 14:25 ? 次閱讀

什么是裝飾器模式

裝飾器模式(Decorator Pattern): 在不改變對象自身的基礎上,在程序運行期間給對象動態的添加職責;

感覺和繼承如出一轍,不改變父類,子類可拓展功能;

優點

  1. 裝飾類和被裝飾類可以獨立發展,不會相互耦合
  2. 相比于繼承,更加的輕便、靈活
  3. 可以動態擴展一個實現類的功能,不必修改原本代碼

缺點

  1. 會產生很多的裝飾類,增加了系統的復雜性。
  2. 這種比繼承更加靈活機動的特性,也同時意味著裝飾模式比繼承易于出錯,排錯也很困難,對于多次裝飾的對象,調試時尋找錯誤可能需要逐級排查,較為繁瑣。

使用場景

  1. 對已有的目標功能存在不足,需要增強時,擴展類的功能。
  2. 動態增加功能,動態撤銷

裝飾器模式和代理模式的區別

  • 代理是全權代理,目標根本不對外,全部由代理類來完成;裝飾是增強,是輔助,目標仍然可以自行對外提供服務,裝飾器只起增強作用。
  • 裝飾器模式強調的是: 增強、新增行為 ;代理模式強調的是: 對代理的對象施加控制,但不對對象本身的功能進行增強 。
  • 裝飾器模式:生效的對象還是原本的對象;代理模式:生效的是新的對象(代理對象)

圖片
裝飾器和代理的區別

裝飾器的簡單實現

場景 :天氣太熱了,喝點兒冰水解解暑;加點兒檸檬片,讓果汁好喝點兒

先定義一個喝水的接口

public interface Drink {
    /**
     * 喝水
     */
    void drink();
}

寫一個接口的實現

public class DrinkWater implements Drink {

    @Override
    public void drink() {
        System.out.println("喝水");
    }

}

一個簡單的裝飾器

public class DrinkDecorator implements Drink {

    private final Drink drink;

    public DrinkDecorator(Drink drink) {
        this.drink = drink;
    }

    @Override
    public void drink() {
        System.out.println("先加點兒檸檬片");
        drink.drink();
    }

}

開始測試

public class DrinkMain {
    public static void main(String[] args) {
        Drink drink = new DrinkWater();
        drink = new DrinkDecorator(drink);
        drink.drink();
    }
}

運行結果

先加點兒檸檬片
喝水

一個簡單的裝飾器模式例子就寫完了;當然這種例子在實際項目中肯定是用不到的,這里只是先了解一下裝飾器模式

裝飾器模式實戰

場景: 項目一期開發的時候,并沒有給鑒權部分設置緩存;二期開發考慮到性能問題,想要給鑒權部分加上緩存,這里就選擇了使用裝飾器模式進行處理;

這里使用的緩存是spring的 spring-cache,不了解沒關系,知道幾個注解什么意思就行

@Cacheable 表示要對方法返回值進行緩存

@CacheEvict 刪除緩存注解

為了簡潔,以下代碼均為偽代碼

首先,需要一個權限的接口和實現類

public interface IDataAccessor {
    /**
     * 根據部門上級 id 獲取所有子集部門
     */
    Set< Long > deptFindAllChildrenByParentIds(Collection< Long > parentIds);

    /**
     * 獲取數據范圍內的部門
     */
    Set< Long > deptFindScopeById(Long userId);

實現類(注意這里加了@Service, 交給spring處理)

@Service
public class ScopeDataAccessorImpl implements IDataAccessor {
    @Autowired
    private IDepartmentService departmentService;
    
    @Autowired
    private INodeScopeService nodeScopeService;

    @Override
    public Set< Long > deptFindAllChildrenByParentIds(Collection< Long > parentIds) {
        Set< Long > result = new HashSet<  >();
        departmentService.departmentChildren(parentIds, result);
        return result;
    }
    
    @Override
    public Set< Long > deptFindScopeById(Long userId) {
        return nodeScopeService.deptFindScopeById(userId);
    }
}

接下來就是對之前的代碼進行裝飾,定義一個裝飾器的實現類

(這個類沒有 @Component, 沒有直接交給spring管理;加了注解會報錯:找到了2個bean)

public class DataAccessorDecorator implements IDataAccessor {
    private final IDataAccessor iDataAccessor;

    public DataAccessorDecorator(IDataAccessor iDataAccessor) {
        this.iDataAccessor = iDataAccessor;
    }

    @Cacheable(cacheNames = "dept:parentId", key = "#p0", sync = true)
    @Override
    public Set< Long > deptFindAllChildrenByParentIds(Collection< Long > parentIds) {
        return iDataAccessor.deptFindAllChildrenByParentIds(parentIds);
    }

    @Cacheable(cacheNames = "dept:scope:userId", key = "#p0", sync = true)
    @Override
    public Set< Long > deptFindScopeById(Long userId) {
        return iDataAccessor.deptFindScopeById(nodeId,userId);
    }
}

接下來還需要將這個裝飾器的類注冊到spring中

@Configuration
@ConditionalOnBean({IDataAccessor.class})
public class Config {
    
    @Bean
    @ConditionalOnBean({IDataAccessor.class})
    public DataAccessorDecorator dataAccessorDecorator(IDataAccessor iDataAccessor) {
        return new DataAccessorDecorator(iDataAccessor);
    }
}

根據業務,維護緩存更新;這里使用的監聽部門和員工的變更事件

@Component
public class DataScopeEvict {

    /**
     * 清空部門相關緩存
     */
    @CacheEvict(cacheNames = {"dept:parentId"}, allEntries = true)
    public void department() {
    }

    /**
     * 清空用戶相關緩存
     */
    @CacheEvict(cacheNames = {"dept:scope:userId"}, allEntries = true)
    public void user() {
    }
}
@Component
public class ScopeDataEventListener {
    @Autowired
    private DataScopeEvict evict;
    
 /**
     * 監聽部門變更事件
     */
    @EventListener
    public void departmentEvent(DepartmentChangeEvent event) {
        // 1 增加 2 刪除 3 上級部門變更
        evict.department();
    }

    /**
     * 監聽user變更事件
     */
    @EventListener
    public void userEvent(UserChangeEvent event) {
        // 2 刪除 3 主部門變更
        if (event.getType().equals(2) || event.getType().equals(3)) {
            evict.user();
        }
    }
}

一切準備就緒,使用的時候直接使用裝飾器類就好了

@Service
public class UserService {
    
    @Autowired
    DataAccessorDecorator scopeDataAccessor;

    
    public Set< Long > deptFindAllChildrenByParentIds(Collection< Long > parentIds) {
        return scopeDataAccessor.deptFindAllChildrenByParentIds(parentIds);
    }
    
    
    public Set< Long > deptFindScopeById(Long userId) {
        return scopeDataAccessor.deptFindScopeById(userId);
    }
    
}

以上就是一個將裝飾器模式應用到實際項目的例子;

在這個例子中,使用裝飾器模式增強了原本的代碼,不修改原本的代碼,原本的代碼也能正確提供服務,只不過沒有使用緩存;只要方法名命名一致,只需修改注入的字段就可以升級完成,升級成本還是很低的。

這波使用裝飾器模式加緩存的操作寫到項目中,直接讓你的代碼 B ge pull full

小結

雖然使用裝飾器模式看起來B格高,但還是要注意自己項目的場景,選擇適合的方式解決問題。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 接口
    +關注

    關注

    33

    文章

    8686

    瀏覽量

    151655
  • 緩存
    +關注

    關注

    1

    文章

    240

    瀏覽量

    26724
  • 代碼
    +關注

    關注

    30

    文章

    4820

    瀏覽量

    68881
收藏 人收藏

    評論

    相關推薦

    適配器模式代理模式區別

      代理模式  組成:  抽象角色:通過接口或抽象類聲明真實角色實現的業務方法?! ?b class='flag-5'>代理角色:實現抽象角色,是真實角色的代理,通過真實角色的業務邏輯方法來實現抽象方法,并可以附加自己的
    發表于 10-22 15:17

    MCU模式和RGB模式區別

    模式(也寫成MPU模式的)。只有TFT模塊才有RGB接口。但應用比較多的就是MCU模式和RGB模式,區別有以下幾點:1.MCU接口:會解碼命
    發表于 11-03 08:53

    適配器模式裝飾模式代理模式區別

    適配器模式裝飾模式代理模式都屬于設計模式中的結
    發表于 10-18 15:53 ?1.7w次閱讀
    適配器<b class='flag-5'>模式</b>、<b class='flag-5'>裝飾</b><b class='flag-5'>器</b><b class='flag-5'>模式</b>、<b class='flag-5'>代理</b><b class='flag-5'>模式</b>的<b class='flag-5'>區別</b>

    適配器模式代理模式區別

    適配器模式:適配器模式有時候也稱包裝樣式或者包裝。將一個類的接口轉接成用戶所期待的。代理模式:為其他對象提供一種代理以控制對這個對象的訪問。
    發表于 01-12 11:56 ?5284次閱讀
    適配器<b class='flag-5'>模式</b>和<b class='flag-5'>代理</b><b class='flag-5'>模式</b>的<b class='flag-5'>區別</b>

    適配器模式裝飾模式區別

    裝飾模式指的是在不必改變原類文件和使用繼承的情況下,動態地擴展一個對象的功能。它是通過創建一個包裝對象,也就是裝飾來包裹真實的對象。在計算機編程中,適配器模式(有時候也稱包裝樣式或者包
    發表于 01-15 10:31 ?7024次閱讀
    適配器<b class='flag-5'>模式</b>和<b class='flag-5'>裝飾</b><b class='flag-5'>模式</b>的<b class='flag-5'>區別</b>

    西門子PLC的等時模式和非等時模式區別

    西門子PLC的等時模式和非等時模式區別說明。
    發表于 04-23 15:58 ?4次下載

    LCD MCU模式和RGB模式

    應用比較多的就是MUC模式和RGB模式區別有以下幾點:1.MCU接口:會解碼命令,由timing generator產生時序信號,驅動COM和SEG驅。RGB接口:在寫LCD re
    發表于 10-28 09:50 ?19次下載
    LCD MCU<b class='flag-5'>模式</b>和RGB<b class='flag-5'>模式</b>

    GoF給裝飾模式的定義

    的源碼,就會發現 middleware 功能的實現用的就是裝飾模式(Decorator Pattern)。
    的頭像 發表于 06-29 10:22 ?841次閱讀

    GoF設計模式代理模式

    它是一個使用率非常高的設計模式,在現實生活中,也是很常見。比如,演唱會門票黃牛。假設你需要看一場演唱會,但官網上門票已經售罄,于是就當天到現場通過黃牛高價買了一張。在這個例子中,黃牛就相當于演唱會門票的代理,在正式渠道無法購買門票的情況下,你通過
    的頭像 發表于 10-17 09:45 ?960次閱讀

    嵌入式C語言軟件設計之裝飾模式(Decorator Pattern)

    裝飾模式(Decorator Pattern),是結構型設計模式的一種,裝飾
    發表于 03-01 10:55 ?432次閱讀

    演示裝飾模式的用法

    裝飾模式(Decorator Pattern)允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬于結構型模式,它是
    的頭像 發表于 06-08 11:16 ?593次閱讀
    演示<b class='flag-5'>裝飾</b><b class='flag-5'>器</b><b class='flag-5'>模式</b>的用法

    設計模式結構性:代理模式

    代理模式(Proxy Pattern)中,一個類代表另一個類的功能。這種類型的設計模式屬于結構型模式。
    的頭像 發表于 06-09 15:27 ?862次閱讀
    設計<b class='flag-5'>模式</b>結構性:<b class='flag-5'>代理</b><b class='flag-5'>模式</b>

    設計模式代理模式的使用場景

    設計模式在我看來更像是一種設計思維或設計思想,它就像《孫子兵法》一樣,為你的項目工程提供方向,讓你的項目工程更加健壯、靈活,延續生命力。本文即將分享的是設計模式的其中一種:代理模式
    的頭像 發表于 10-08 14:34 ?1080次閱讀
    設計<b class='flag-5'>模式</b>中<b class='flag-5'>代理</b><b class='flag-5'>模式</b>的使用場景

    示波器滾動模式與標準模式區別

    示波器滾動模式與標準模式區別? 示波器是一種電子測試儀器,它用于顯示電壓隨時間變化的波形圖。示波器可以設置為兩種顯示模式:滾動模式和標準
    的頭像 發表于 11-07 10:13 ?2304次閱讀

    網絡橋接模式是什么? 網絡橋接模式和路由模式區別

    網絡橋接模式是一種網絡連接方式,它可以將多個設備連接在一起,使它們可以相互通信。在網絡橋接模式下,每個設備都可以直接與其他設備通信,而不需要經過路由或其他中間設備。這種連接方式通常用于局域網中
    的頭像 發表于 05-10 13:48 ?4615次閱讀
    主站蜘蛛池模板: 俄罗斯女肥臀大屁BBW| 国产午夜精品自在自线之la| 亚洲精品第一页中文字幕| xxx性欧美在线| 伦理在线影院伦理电影 | 鲁一鲁亚洲无线码| 最近中文字幕MV高清在线| 白银谷在线观看| 欧美一区二区高清| 亚洲精品无码一区二区三区四虎| 国产精品国产三级国产an| 丝袜美女被艹| 国产精品女上位好爽在线短片| 视频一区国产在线第一页| 国产精品人妻无码久久久蜜桃臀| 亚洲AV蜜桃永久无码精品红樱桃| 国内精品久久人妻无码HD浪潮| 亚洲中文字幕乱码熟女在线| 持田香织abc| 日本视频久久| 又亲又揉摸下面视频免费看| 久久黄色免费| 18岁末年禁止观看免费1000个| 免费成人小视频| yin乱教师系列合集| 色一情一乱一伦一区二区三区| 国产精品永久在线| 亚洲欧洲日产国码中学| 国产精品久久久久久久久久久| 亚洲 欧美 制服 校园 动漫| 国自产精品手机在线视频| 一个人看的www视频动漫版| 麻豆国产原创中文AV网站| JAPANBABES11学生老师| 无码欧美喷潮福利XXXX| 超碰在线线公开免费视频| 午夜噜噜噜私人影院在线播放| qvod理论电影| 麻生希第一部快播| 丰满的女朋友韩国版在线观看| 亚洲高清无码在线 视频|