設(shè)計(jì)模式 —— 7種結(jié)構(gòu)型設(shè)計(jì)模式大總結(jié)

來源:《圖說設(shè)計(jì)模式》

結(jié)構(gòu)型模式(Structural Pattern)描述如何將類或者對象結(jié)合在一起形成更大的結(jié)構(gòu)仁锯,就像搭積木业崖,可以通過 簡單積木的組合形成復(fù)雜的蓄愁、功能更為強(qiáng)大的結(jié)構(gòu)腻要。

結(jié)構(gòu)型模式可以分為類結(jié)構(gòu)型模式和對象結(jié)構(gòu)型模式:

  • 類結(jié)構(gòu)型模式關(guān)心類的組合,一般只存在繼承關(guān)系和實(shí)現(xiàn)關(guān)系涝登。

  • 對象結(jié)構(gòu)型模式關(guān)心類與對象的組合雄家,一般關(guān)系為關(guān)聯(lián)關(guān)系。 根據(jù)“合成復(fù)用原則”胀滚,在系統(tǒng)中盡量使用關(guān)聯(lián)關(guān)系來替代繼承關(guān)系趟济,因此大部分類結(jié)構(gòu)型模式都是對象結(jié)構(gòu)型模式咽笼。

包含模式

  • 適配器模式(Adapter)
    重要程度:4

  • 橋接模式(Bridge)
    重要程度:3

  • 組合模式(Composite)
    重要程度:4

  • 裝飾模式(Decorator)
    重要程度:3

  • 外觀模式(Facade)
    重要程度:5

  • 享元模式(Flyweight)
    重要程度:1

  • 代理模式(Proxy)
    重要程度:4

一顷编、適配器模式(Adapter)

模式動(dòng)機(jī)

適配器可以使由于接口不兼容而不能交互的類可以一起工作。類似于電源適配器的設(shè)計(jì)剑刑。

模式結(jié)構(gòu)

適配器模式包含如下角色:

Target:目標(biāo)抽象類
Adapter:適配器類
Adaptee:適配者類
Client:客戶類

適配器模式有對象適配器和類適配器兩種實(shí)現(xiàn):

  1. 類適配器:


    類適配器

    類適配器媳纬,Adapter 類既繼承了 Adaptee (被適配類),也實(shí)現(xiàn)了 Target 接口

  2. 對象適配器:


    對象適配器

    對象適配器施掏,它不是使用多繼承或繼承再實(shí)現(xiàn)的方式钮惠,而是使用直接關(guān)聯(lián),或者稱為委托的方式七芭。

從類圖中我們也可以看到 對象適配器比起類適配器 需要修改的只不過就是 Adapter 類的內(nèi)部結(jié)構(gòu)素挽,即 Adapter 自身必須先擁有一個(gè)被適配類的對象,再把具體的特殊功能委托給這個(gè)對象來實(shí)現(xiàn)狸驳。使用對象適配器模式预明,可以使得 Adapter 類(適配類)根據(jù)傳入的 Adaptee 對象達(dá)到適配多個(gè)不同被適配類的功能,當(dāng)然耙箍,此時(shí)我們可以為多個(gè)被適配類提取出一個(gè)接口或抽象類撰糠。這樣看起來的話,似乎對象適配器模式更加靈活一點(diǎn)辩昆。

代碼分析

典型的類適配器代碼

// 已存在的阅酪、具有特殊功能、但不符合我們既有的標(biāo)準(zhǔn)接口的類
class Adaptee {
    public void specificRequest() {
        System.out.println("被適配類具有 特殊功能...");
    }
}
// 目標(biāo)接口,或稱為標(biāo)準(zhǔn)接口
interface Target {
    public void request();
}

// 具體目標(biāo)類遮斥,只提供普通功能
class ConcreteTarget implements Target {
    public void request() {
        System.out.println("普通類 具有 普通功能...");
    }
}
 
// 適配器類,繼承了被適配類扇丛,同時(shí)實(shí)現(xiàn)標(biāo)準(zhǔn)接口
class Adapter extends Adaptee implements Target{
    public void request() {
        super.specificRequest();
    }
}

典型的對象適配器代碼

// 適配器類术吗,直接關(guān)聯(lián)被適配類,同時(shí)實(shí)現(xiàn)標(biāo)準(zhǔn)接口
class Adapter implements Target{
    // 直接關(guān)聯(lián)被適配類
    private Adaptee adaptee;
    
    // 可以通過構(gòu)造函數(shù)傳入具體需要適配的被適配類對象
    public Adapter (Adaptee adaptee) {
        this.adaptee = adaptee;
    }
    
    public void request() {
        // 這里是使用委托的方式完成特殊功能
        this.adaptee.specificRequest();
    }
}

兩種方式的區(qū)別 :

  • 對象適配器模式可以直接使用一個(gè)已有的Adaptee的實(shí)例來轉(zhuǎn)換接口帆精。
  • 類適配器繼承了Adaptee,所以可以通過覆寫來擴(kuò)展SpecificRequest()
  • 類適配器模式因?yàn)槭抢^承所以相對靜態(tài)较屿,而對象適配器模式是包含是組合相對靈活(可以通過寫adaptee子類擴(kuò)展功能)
優(yōu)點(diǎn)

將目標(biāo)類和適配者類解耦,增加了類的透明性和復(fù)用性卓练,靈活性和擴(kuò)展性都非常好隘蝎,完全符合“開閉原則”。

缺點(diǎn)

類適配器一次最多只能適配一個(gè)適配者類襟企,使用有一定的局限性嘱么。(不能多繼承)

而對象適配器雖然可以把適配者類和它的子類都適配到目標(biāo)接口,但是更改適配者的方法十分麻煩顽悼,既需要更改適配器曼振,也需要更改適配者

應(yīng)用

JDBC驅(qū)動(dòng)軟件就是一個(gè)介于JDBC接口和數(shù)據(jù)庫引擎接口之間的適配器軟件。

擴(kuò)展

當(dāng)不需要全部實(shí)現(xiàn)接口提供的方法時(shí)蔚龙,可先設(shè)計(jì)一個(gè)抽象類實(shí)現(xiàn)接口冰评,并為該接口中每個(gè)方法提供一個(gè)默認(rèn)實(shí)現(xiàn)(空方法),那么該抽象類的子類可有選擇地覆蓋父類的某些方法來實(shí)現(xiàn)需求木羹,它適用于一個(gè)接口不想使用其所有的方法的情況甲雅。因此也稱為單接口適配器模式。

二坑填、橋接模式(Bridge)

模式動(dòng)機(jī)

設(shè)想如果要繪制矩形抛人、圓形、橢圓脐瑰、正方形函匕,我們至少需要4個(gè)形狀類,但是如果繪制的圖形需要具有不同的顏色蚪黑,如紅色盅惜、綠色、藍(lán)色等忌穿,此時(shí)至少有如下兩種設(shè)計(jì)方案:

第一種設(shè)計(jì)方案是為每一種形狀都提供一套各種顏色的版本抒寂。
第二種設(shè)計(jì)方案是根據(jù)實(shí)際需要對形狀和顏色進(jìn)行組合
對于有兩個(gè)變化維度的系統(tǒng),采用方案二來進(jìn)行設(shè)計(jì)系統(tǒng)中類的個(gè)數(shù)更少掠剑,且系統(tǒng)擴(kuò)展更為方便屈芜。設(shè)計(jì)方案二即是橋接模式的應(yīng)用。橋接模式將繼承關(guān)系轉(zhuǎn)換為關(guān)聯(lián)關(guān)系,從而降低了類與類之間的耦合井佑,減少了代碼編寫量属铁。

模式定義

橋接模式(Bridge Pattern):將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化躬翁。它是一種對象結(jié)構(gòu)型模式焦蘑。

模式結(jié)構(gòu)

橋接模式包含如下角色:

Abstraction:抽象類
RefinedAbstraction:擴(kuò)充抽象類
Implementor:實(shí)現(xiàn)類接口
ConcreteImplementor:具體實(shí)現(xiàn)類

Paste_Image.png
代碼分析
interface Implementor{
 
  void operationImpl();
}
 
abstract class Abstraction{
  protected Implementor implementor;
 
  public Abstraction(Implementor implementor){
    this.implementor = implementor;
  }
 
  public void operation(){
    implementor.operationImpl();
  }
}
 
class ConcreteImplementorA implements Implementor {
  @Override
  public void operationImpl() {
    System.out.println("具體實(shí)現(xiàn)A");
  }  
}
 
class ConcreteImplementorB implements Implementor {
  @Override
  public void operationImpl() {
    System.out.println("具體實(shí)現(xiàn)B");
  }  
}
 
class RefinedAbstraction extends Abstraction{
 
  public RefinedAbstraction(Implementor implementor) {
    super(implementor);
  }
 
  public void otherOperation(){
    System.out.println("其他操作");
  }
}
 
public class MainTest {
 
  public static void main(String arg[]) {
    Implementor implementor = new ConcreteImplementorA();
    RefinedAbstraction abstraction = new RefinedAbstraction(implementor);
    abstraction.operation();
    abstraction.otherOperation();
  }
}
擴(kuò)展
  • 橋接模式和適配器模式的區(qū)別

很多時(shí)候經(jīng)常容易把橋接模式和適配器模式弄混。那什么時(shí)候用橋接盒发,什么時(shí)候用適配器呢 例嘱?

共同點(diǎn):

橋接和適配器都是讓兩個(gè)東西配合工作

不同點(diǎn):

適配器:改變已有的兩個(gè)接口,讓他們相容宁舰。

橋接模式:分離抽象化和實(shí)現(xiàn)拼卵,使兩者的接口可以不同,目的是分離蛮艰。

所以說腋腮,如果你拿到兩個(gè)已有模塊,想讓他們同時(shí)工作壤蚜,那么你使用的適配器低葫。 如果你還什么都沒有,但是想分開實(shí)現(xiàn)仍律,那么橋接是一個(gè)選擇嘿悬。

橋接是先有橋,才有兩端的東西 適配是先有兩邊的東西水泉,才有適配器 善涨。

橋模式并不同于適配器模式,適配器模式其實(shí)是一個(gè)事后諸葛亮草则,當(dāng)發(fā)現(xiàn)以前的東西不適用了才去做一個(gè)彌補(bǔ)的措施钢拧。橋模式相對來說所做的改變比適配器模式早,它可以適用于有兩個(gè)甚至兩個(gè)以上維度的變化炕横。

橋接模式將繼承關(guān)系轉(zhuǎn)換為關(guān)聯(lián)關(guān)系源内,從而降低了類與類之間的耦合,減少了代碼編寫量份殿。

三膜钓、組合模式(Composite)

模式動(dòng)機(jī)

將對象組合成樹形結(jié)構(gòu)以表示‘部分-整體’的層次結(jié)構(gòu)。組合模式使得用戶對耽擱對象和組合對象的使用具有一致性卿嘲。

模式結(jié)構(gòu)
Paste_Image.png
代碼分析

public abstract class Company {  
    private String name;  
  
    public Company(String name) {  
        this.name = name;  
    }  
  
    public Company() {  
    }  

    protected abstract void add(Company company);  
  
    protected abstract void remove(Company company);  
  
    protected abstract void display(int depth);  
}  
  
public class ConcreteCompany extends Company {  
    private List<Company> cList;  
  
    public ConcreteCompany() {  
        cList = new ArrayList<Company>();  
    }  
  
    public ConcreteCompany(String name) {  
        super(name);   
        cList = new ArrayList<Company>() ;   
    }  
  
    @Override  
    protected void add(Company company) {  
        cList.add(company);  
    }  
  
    @Override  
    protected void display(int depth) {  
     
        StringBuilder sb = new StringBuilder("");  
        for (int i = 0; i < depth; i++) {  
            sb.append("-");   
        }  
        System.out.println(new String(sb) + this.getName());  
        for (Company c : cList) {  
            c.display(depth + 2);  
        }  
    }  
  
    @Override  
    protected void remove(Company company) {  
        cList.remove(company);  
    }  
}  
  
public class FinanceDepartment extends Company {  
      
      
    public FinanceDepartment(){  
          
    }  
      
    public FinanceDepartment(String name){  
        super(name);  
    }  
      
    @Override  
    protected void add(Company company) {  
  
    }  
  
    @Override  
    protected void display(int depth) {  
        StringBuilder sb = new StringBuilder("");  
        for (int i = 0; i < depth; i++) {  
            sb.append("-");  
        }  
        System.out.println(new String(sb) + this.getName() ) ;   
    }  
  
    @Override  
    protected void remove(Company company) {  
          
    }  
      
}  
  
public class HRDepartment extends Company {  
      
      
    public HRDepartment(){  
          
    }  
      
    public HRDepartment(String name){  
        super(name);  
    }  
      
    @Override  
    protected void add(Company company) {  
  
    }  
  
    @Override  
    protected void display(int depth) {  
        StringBuilder sb = new StringBuilder("");  
        for (int i = 0; i < depth; i++) {  
            sb.append("-");   
        }  
        System.out.println(new String(sb) + this.getName() ) ;   
    }  
  
    @Override  
    protected void remove(Company company) {  
          
    }  
      
}  
  

public class Client {  
  
  
    public static void main(String[] args) {  
        
        Company root = new ConcreteCompany();  
        root.setName("北京總公司");  
        root.add(new HRDepartment("總公司人力資源部"));  
        root.add(new FinanceDepartment("總公司財(cái)務(wù)部"));  
        Company shandongCom = new ConcreteCompany("山東分公司");  
        shandongCom.add(new HRDepartment("山東分公司人力資源部"));  
        shandongCom.add(new FinanceDepartment("山東分公司賬務(wù)部"));  
       
        Company jinanCom = new ConcreteCompany("濟(jì)南辦事處");  
        jinanCom.add(new FinanceDepartment("濟(jì)南辦事處財(cái)務(wù)部"));  
        jinanCom.add(new HRDepartment("濟(jì)南辦事處人力資源部"));   
        shandongCom.add(jinanCom);  
       
        root.add(shandongCom);  
        root.display(0);  
    }  
  
}  

類似于樹

四颂斜、裝飾模式(Decorator)

模式動(dòng)機(jī)

一般有兩種方式可以實(shí)現(xiàn)給一個(gè)類或?qū)ο笤黾有袨椋?/p>

  1. 繼承機(jī)制
  2. 關(guān)聯(lián)機(jī)制,即將一個(gè)類的對象嵌入另一個(gè)對象中拾枣,由另一個(gè)對象來決定是否調(diào)用嵌入對象的行為以便擴(kuò)展自己的行為沃疮,我們稱這個(gè)嵌入的對象為裝飾器(Decorator)

裝飾模式可以在不需要?jiǎng)?chuàng)造更多子類的情況下盒让,將對象的功能加以擴(kuò)展。這就是裝飾模式的模式動(dòng)機(jī)司蔬。

模式定義

裝飾模式(Decorator Pattern) :動(dòng)態(tài)地給一個(gè)對象增加一些額外的職責(zé)(Responsibility)邑茄,它是一種對象結(jié)構(gòu)型模式。

模式結(jié)構(gòu)

裝飾模式包含如下角色:

Component: 抽象構(gòu)件
ConcreteComponent: 具體構(gòu)件
Decorator: 抽象裝飾類
ConcreteDecorator: 具體裝飾類

Paste_Image.png
代碼分析

現(xiàn)在需要一個(gè)漢堡俊啼,主體是雞腿堡肺缕,可以選擇添加生菜、醬吨些、辣椒等等許多其他的配料搓谆,這種情況下就可以使用裝飾者模式炒辉。


//漢堡基類(被裝飾者)
public abstract class Humburger {    
        
    protected  String name ;    
        
    public String getName(){    
        return name;    
    }    
        
    public abstract double getPrice();    
    
}    
//雞腿堡類(被裝飾者的初始狀態(tài)豪墅,有些自己的簡單裝飾)
public class ChickenBurger extends Humburger {    
        
    public ChickenBurger(){    
        name = "雞腿堡";    
    }    
    
    @Override    
    public double getPrice() {    
        return 10;    
    }    
}
//配料的基類(裝飾者,用來對漢堡進(jìn)行多層裝飾黔寇,每層裝飾增加一些配料)
public abstract class Condiment extends Humburger {    
        
    public abstract String getName();    
    
}    
//生菜(裝飾者的第一層)
 public class Lettuce extends Condiment {    
        
    Humburger humburger;    
        
    public Lettuce(Humburger humburger){    
        this.humburger = humburger;    
    }    
    
    @Override    
    public String getName() {    
        return humburger.getName()+" 加生菜";    
    }    
    
    @Override    
    public double getPrice() {    
        return humburger.getPrice()+1.5;    
    }    
    
}    
//辣椒(裝飾者的第二層)
public class Chilli extends Condiment {    
        
    Humburger humburger;    
        
    public Chilli(Humburger humburger){    
        this.humburger = humburger;    
            
    }    
    
    @Override    
    public String getName() {    
        return humburger.getName()+" 加辣椒";    
    }    
    
    @Override    
    public double getPrice() {    
        return humburger.getPrice();  //辣椒是免費(fèi)的哦    
    }    
    
}    
//測試類
public static void main(String[] args) {    
        Humburger humburger = new ChickenBurger();    
        System.out.println(humburger.getName()+"  價(jià)錢:"+humburger.getPrice());    
        Lettuce lettuce = new Lettuce(humburger);    
        System.out.println(lettuce.getName()+"  價(jià)錢:"+lettuce.getPrice());    
        Chilli chilli = new Chilli(humburger);    
        System.out.println(chilli.getName()+"  價(jià)錢:"+chilli.getPrice());    
        Chilli chilli2 = new Chilli(lettuce);    
        System.out.println(chilli2.getName()+"  價(jià)錢:"+chilli2.getPrice());    
    }      
應(yīng)用

Java 的I/O API就是使用裝飾模式實(shí)現(xiàn)的

五偶器、外觀模式(Facade)

模式定義

外部與一個(gè)子系統(tǒng)的通信必須通過一個(gè)統(tǒng)一的外觀對象進(jìn)行,為子系統(tǒng)中的一組接口提供一個(gè)一致的界面缝裤,外觀模式定義了一個(gè)高層接口屏轰,這個(gè)接口使得子系統(tǒng)更加容易使用。外觀模式又稱為門面模式憋飞,它是一種對象結(jié)構(gòu)型模式霎苗。

模式結(jié)構(gòu)

外觀模式包含如下角色:

Facade: 外觀角色
SubSystem:子系統(tǒng)角色

Paste_Image.png
代碼分析
int main()
{
    Facade fa;
    fa.wrapOpration();
    return 0;
}
class Facade
{

public:
    Facade();
    virtual ~Facade();
    void wrapOpration();
private:
    SystemC *m_SystemC;
    SystemA *m_SystemA;
    SystemB *m_SystemB;
};

Facade::Facade(){
    m_SystemA  = new SystemA();
    m_SystemB = new SystemB();
    m_SystemC = new SystemC();
}

void Facade::wrapOpration(){
    m_SystemA->operationA();
    m_SystemB->operationB();
    m_SystemC->opeartionC();
}
模式分析

據(jù)“單一職責(zé)原則”,在軟件中將一個(gè)系統(tǒng)劃分為若干個(gè)子系統(tǒng)有利于降低整個(gè)系統(tǒng)的復(fù)雜性榛做,一個(gè)常見的設(shè)計(jì)目標(biāo)是使子系統(tǒng)間的通信和相互依賴關(guān)系達(dá)到最小唁盏,而達(dá)到該目標(biāo)的途徑之一就是引入一個(gè)外觀對象,它為子系統(tǒng)的訪問提供了一個(gè)簡單而單一的入口检眯。

外觀模式也是“迪米特法則”的體現(xiàn)厘擂,通過引入一個(gè)新的外觀類可以降低原有系統(tǒng)的復(fù)雜度,同時(shí)降低客戶類與子系統(tǒng)類的耦合度锰瘸。

外觀類將客戶端與子系統(tǒng)的內(nèi)部復(fù)雜性分隔開刽严,使得客戶端只需要與外觀對象打交道,而不需要與子系統(tǒng)內(nèi)部的很多對象打交道避凝。

優(yōu)點(diǎn)

對客戶屏蔽子系統(tǒng)組件舞萄,實(shí)現(xiàn)了子系統(tǒng)與客戶之間的松耦合關(guān)系

缺點(diǎn)

在不引入抽象外觀類的情況下,增加新的子系統(tǒng)可能需要修改外觀類的源代碼管削,違背了“開閉原則”鹏氧。

擴(kuò)展
  1. 一個(gè)系統(tǒng)有多個(gè)外觀類
    在一個(gè)系統(tǒng)中可以設(shè)計(jì)多個(gè)外觀類,每個(gè)外觀類都負(fù)責(zé)和一些特定的子系統(tǒng)交互佩谣,向用戶提供相應(yīng)的業(yè)務(wù)功能把还。

  2. 不要通過繼承一個(gè)外觀類在子系統(tǒng)中加入新的行為
    外觀模式的用意是為子系統(tǒng)提供一個(gè)集中化和簡化的溝通渠道,而不是向子系統(tǒng)加入新的行為,新的行為的增加應(yīng)該通過修改原有子系統(tǒng)類或增加新的子系統(tǒng)類來實(shí)現(xiàn)吊履,不能通過外觀類來實(shí)現(xiàn)安皱。

  3. 外觀模式與迪米特法則(最少知道原則)
    外觀類充當(dāng)了客戶類與子系統(tǒng)類之間的“第三者”,降低了客戶類與子系統(tǒng)類之間的耦合度艇炎,外觀模式就是實(shí)現(xiàn)代碼重構(gòu)以便達(dá)到“迪米特法則”要求的一個(gè)強(qiáng)有力的武器酌伊。

  4. 抽象外觀類的引入
    外觀模式最大的缺點(diǎn)在于違背了“開閉原則”,當(dāng)增加新的子系統(tǒng)或者移除子系統(tǒng)時(shí)需要修改外觀類缀踪,可以通過引入抽象外觀類在一定程度上解決該問題居砖,客戶端針對抽象外觀類進(jìn)行編程。對于新的業(yè)務(wù)需求驴娃,不修改原有外觀類奏候,而對應(yīng)增加一個(gè)新的具體外觀類,由新的具體外觀類來關(guān)聯(lián)新的子系統(tǒng)對象唇敞,同時(shí)可以通過修改配置文件來達(dá)到不修改源代碼并更換外觀類的目的蔗草。

六间聊、享元模式(Flyweight)

模式定義

對象的多次復(fù)用

模式結(jié)構(gòu)

享元模式包含如下角色:

Flyweight: 抽象享元類
ConcreteFlyweight: 具體享元類
UnsharedConcreteFlyweight: 非共享具體享元類
FlyweightFactory: 享元工廠類

Paste_Image.png
優(yōu)點(diǎn)

可以極大減少內(nèi)存中對象的數(shù)量蜗搔,使得相同對象或相似對象在內(nèi)存中只保存一份。

缺點(diǎn)

享元模式需要將享元對象的狀態(tài)外部化握爷,而讀取外部狀態(tài)使得運(yùn)行時(shí)間變長旷档。

應(yīng)用

享元模式在編輯器軟件中大量使用模叙,如在一個(gè)文檔中多次出現(xiàn)相同的圖片,則只需要?jiǎng)?chuàng)建一個(gè)圖片對象鞋屈,通過在應(yīng)用程序中設(shè)置該圖片出現(xiàn)的位置范咨,可以實(shí)現(xiàn)該圖片在不同地方多次重復(fù)顯示。

七谐区、代理模式(Proxy)

模式動(dòng)機(jī)

在某些情況下湖蜕,客戶不想或者不能直接引用一個(gè)對 象,此時(shí)可以通過一個(gè)稱之為“代理”的第三者來實(shí)現(xiàn) 間接引用宋列。代理對象可以在客戶端和目標(biāo)對象之間起到 中介的作用昭抒,并且可以通過代理對象去掉客戶不能看到 的內(nèi)容和服務(wù)或者添加客戶需要的額外服務(wù)。

模式定義

給某一個(gè)對象提供一個(gè)代 理炼杖,并由代理對象控制對原對象的引用灭返。它是一種對象結(jié)構(gòu)型模式。

模式結(jié)構(gòu)

代理模式包含如下角色:

Subject: 抽象主題角色
Proxy: 代理主題角色
RealSubject: 真實(shí)主題角色

Paste_Image.png
擴(kuò)展

幾種常用的代理模式

  1. 圖片代理

一個(gè)很常見的代理模式的應(yīng)用實(shí)例就是對大圖瀏覽的控制坤邪。

用戶通過瀏覽器訪問網(wǎng)頁時(shí)先不加載真實(shí)的大圖熙含,而是通過代理對象的方法來進(jìn)行處理,在代理對象的方法中艇纺,先使用一個(gè)線程向客戶端瀏覽器加載一個(gè)小圖片怎静,然后在后臺使用另一個(gè)線程來調(diào)用大圖片的加載方法將大圖片加載到客戶端邮弹。當(dāng)需要瀏覽大圖片時(shí),再將大圖片在新網(wǎng)頁中顯示蚓聘。如果用戶在瀏覽大圖時(shí)加載工作還沒有完成腌乡,可以再啟動(dòng)一個(gè)線程來顯示相應(yīng)的提示信息。通過代理技術(shù)結(jié)合多線程編程將真實(shí)圖片的加載放到后臺來操作夜牡,不影響前臺圖片的瀏覽与纽。

  1. 遠(yuǎn)程代理:遠(yuǎn)程代理可以將網(wǎng)絡(luò)的細(xì)節(jié)隱藏起來,使得客戶端不必考慮網(wǎng)絡(luò)的存在塘装〖庇兀客戶完全可以認(rèn)為被代理的遠(yuǎn)程業(yè)務(wù)對象是局域的而不是遠(yuǎn)程的,而遠(yuǎn)程代理對象承擔(dān)了大部分的網(wǎng)絡(luò)通信工作蹦肴。

  2. 虛擬代理:當(dāng)一個(gè)對象的加載十分耗費(fèi)資源的時(shí)候僚碎,虛擬代理的優(yōu)勢就非常明顯地體現(xiàn)出來了。虛擬代理模式是一種內(nèi)存節(jié)省技術(shù)冗尤,那些占用大量內(nèi)存或處理復(fù)雜的對象將推遲到使用它的時(shí)候才創(chuàng)建听盖。

  3. 動(dòng)態(tài)代理

較為高級的代理模式胀溺,它的典型應(yīng)用就是Spring AOP裂七。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市仓坞,隨后出現(xiàn)的幾起案子背零,更是在濱河造成了極大的恐慌,老刑警劉巖无埃,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徙瓶,死亡現(xiàn)場離奇詭異,居然都是意外死亡嫉称,警方通過查閱死者的電腦和手機(jī)侦镇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來织阅,“玉大人壳繁,你說我怎么就攤上這事±竺蓿” “怎么了闹炉?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長润樱。 經(jīng)常有香客問我渣触,道長,這世上最難降的妖魔是什么壹若? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任嗅钻,我火速辦了婚禮皂冰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘养篓。我一直安慰自己灼擂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布觉至。 她就那樣靜靜地躺著剔应,像睡著了一般。 火紅的嫁衣襯著肌膚如雪语御。 梳的紋絲不亂的頭發(fā)上峻贮,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機(jī)與錄音应闯,去河邊找鬼纤控。 笑死,一個(gè)胖子當(dāng)著我的面吹牛碉纺,可吹牛的內(nèi)容都是我干的船万。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼骨田,長吁一口氣:“原來是場噩夢啊……” “哼耿导!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起态贤,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤舱呻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后悠汽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箱吕,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年柿冲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茬高。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡假抄,死狀恐怖怎栽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情慨亲,我是刑警寧澤婚瓜,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站刑棵,受9級特大地震影響巴刻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蛉签,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一胡陪、第九天 我趴在偏房一處隱蔽的房頂上張望沥寥。 院中可真熱鬧,春花似錦柠座、人聲如沸邑雅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽淮野。三九已至,卻和暖如春吹泡,著一層夾襖步出監(jiān)牢的瞬間骤星,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工爆哑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洞难,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓揭朝,卻偏偏與公主長得像队贱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子潭袱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容