適配器模式和裝飾模式

前言

適配器模式和裝飾模式都是經過組合類或者對象產生更大結構以適應更高層次的邏輯需求。其中裝飾模式是代理模式的一個特殊應用,側重於對類的功能進行增強和減弱。適配器模式則是側重於將源角色轉換的過程。設計模式

目錄

1、適配器模式

一、定義

結構型設計模式關注重點在於多個對象間的組合,而建立型設計模式關注重點在於一個對象內部結構。markdown

適配器模式關鍵點在於轉換,將源角色轉換成目標角色。ide

具體定義以下:函數

將一個類的接口變換成客戶端所期待的另外一種接口,從而使本來因接口不匹配而沒法在一塊兒工做的兩個類可以在一塊兒工做。ui

二、模式原理分析

有三個關鍵角色this

  • 目標類,適配器類即將要適配的抽象類或者接口,就是須要把其餘類轉換成什麼接口spa

  • 適配器類,你想把誰轉換成目標角色,通過適配器包裝,就是一個全新的角色設計

  • 具體適配器類,能夠實內部的類,也能夠是外部的類代理

具體看代碼,會很容易理解code

//源角色
public class Adaptee{
    public void adapteeEat(){
        System.out.println("飯太貴,吃不起");
    }
}
//目標角色
public interface Target{
    public void targetBuyThings();
}
//目標角色的實現類
public class ConcreteTarget implements Target{
    @Override
    public void targetBugThings(){
        System.out.println("東西太貴,買不起");
    }
}
//適配器角色
public class Adapter extends Adaptee implements Target{
    @Override
    public void targetBugThings(){
    	super.adapteeEat();
        System.out.println("東西太貴,買不起");
    }
}

//場景類
public class Client{
    public static void main(String[] args){
        Target target = new Adapter();
        target.targetBuyThings();
    }
}
複製代碼

代碼很簡單,利用了接口,達成了多繼承目的,實現了不一樣類之間的關聯,能夠理解爲中間者將兩個類封裝到了一塊兒。

那若是咱們的Adaptee 信息來自不一樣的類呢?如何處理,以下在構造函數中處理或者 getset方法處理

public class Adapter implements Target{
    private Adaptee adaptee1;
    private Adaptee adaptee2;
    public Adapter(Adaptee adaptee1,Adaptee adaptee2){
        this.adaptee1 = adaptee1;
        this.adaptee2 = adaptee2;
    }
    @Override
    public void targetBugThings(){
    	super.adapteeEat();
        System.out.println("東西太貴,買不起");
    }
}
複製代碼

這裏可能你們還聽過對象適配器和類適配器,這兩種類型適配器,有什麼不一樣?

  • 類適配器是類間繼承

  • 對象適配器是對象的合成關係

三、使用場景

場景比較多,可是隻須要記住,你須要修改一個已經投產中的接口時,適配器模式多是最適合的模式,例如系統擴展了,須要使用一個已經有的或者新創建的類,這是能夠考慮適配器模式。或者是不一樣數據格式、協議須要轉換的時候,好比,API 網關中常常須要對 iOS、安卓、H5 等不一樣的客戶端進行數據和通訊協議上的適配轉換,這時網關就是一個是適配器。

適配器模式通常是用於解決服役項目問題,最好不要在詳細階段考慮它,畢竟主要場景仍是在擴展應用方面。

四、優勢

  • 讓兩個沒有任務關係的類在一塊兒運行

  • 增長了類的透明型,具體的適配者類中新增功能隻影響適配者類,而對於使用目標類的客戶端類來講是透明的(使用目標類接口)

  • 提升了類的複用度

  • 符合開閉原則

  • 知足里氏替換原則

五、缺點

  • 一次只能適配一個抽象類或者接口

  • 過分嵌套會致使接口臃腫

  • 目標接口依賴太多適配接口,修改目標接口會致使全部適配接口都得改,太多Adapter 依賴 Target, Target 修改了方法,全部Adapter 都須要改。對應以前提到的 Adaptee不少的狀況

2、裝飾模式

一、定義

動態地給一個對象添加一些額外地職責

二、模式分析

//抽象構件
public abstract class Component{
	//抽象方法
    public abstract void operate();
}
//具體構件
public class ConcreteComponent extends Component{
    @Override
    public void operate(){
        System.out.println("operate car");
    }
}

//抽象裝飾者
public abstract class Decorator extends Component{
    private Component component = null;
    public Decorator(Component component){
        this.component = component;
    }
    //委託給被修飾者執行
    @Override
    public void operate(){
        this.component.operate();
    }
}
//具體裝飾類
public class ConcreteDecorator1 extends Decorator{
    //定義被修飾者
    puiblic ConcreteDecorator1(Component component){
        super(component);
    }
    //定義本身的修飾方法
    private void method1(){
        System.out.println("method1修飾");
    }
    //重寫父類
    public void operate(){
        this.method1();
        super.operate();
    }
}
複製代碼

最簡單的理解就是,用一個類持有另外一個類,新類裏方法調用能夠操做另外一個類的方法,這裏的方法要留意一下,都是operate方法,這種模式其實也能夠說是繼承關係的一個替代方案

原始方法和裝飾方法的執行順序在具體的裝飾類是固定的,能夠經過方法重載實現多種執行順序

三、使用場景

  • 須要動態擴展一個類的功能,或者給一個類增長附加功能

  • 須要爲一批兄弟類進行改裝

  • 經過順序組合包裝的方式來附加擴張功能的場景

例如數據上報,埋點,新功能須要更加詳細,能夠考慮下裝飾者模式

四、優勢

  • 裝飾類和被裝飾類能夠獨立發展,不會相互耦合(看上面的具體代碼,這兩個類都實現了基礎類接口)

  • 動態擴展功能

  • 能夠在統一行爲上組合幾種行爲

  • 知足單一職責原則

五、缺點

  • 在調用鏈中刪除某個裝飾器時須要修改代碼,爲何?看下面代碼

    Component component = new ConcreteComponent();
    //第一次修飾
    component = new ConcreteDecorator1(component);
    //第二次修飾
    component = new ConcreteDecorator2(component);
    //修飾後運行
    component.operate();
    複製代碼
  • 若是修飾類嵌套過多,會增長代碼的理解難度,後續維護和排查問題的難度

3、區別

適配器模式和裝飾者模式都屬於結構型模式,功能都相似,都是包裝做用。

裝飾模式強調的是 動態擴展功能,全部裝飾類都有一個共同的父類,而適配器模式側重於轉換,經過繼承和實現方式,將源角色轉換成目標角色,

相關文章
相關標籤/搜索