国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - PHP教程 - PHP設(shè)計模式(五)適配器模式Adapter實例詳解【結(jié)構(gòu)型】

PHP設(shè)計模式(五)適配器模式Adapter實例詳解【結(jié)構(gòu)型】

2020-06-28 14:08規(guī)速 PHP教程

這篇文章主要介紹了PHP設(shè)計模式:適配器模式Adapter,結(jié)合實例形式詳細(xì)分析了PHP適配器模式Adapter基本概念、功能、原理、用法及操作注意事項,需要的朋友可以參考下

本文實例講述了PHP設(shè)計模式適配器模式Adapter。分享給大家供大家參考,具體如下:

1. 概述:

 

         接口的改變,是一個需要程序員們必須(雖然很不情愿)接受和處理的普遍問題。程序提供者們修改他們的代碼;系統(tǒng)庫被修正;各種程序語言以及相關(guān)庫的發(fā)展和進(jìn)化。

        例子1:iphone4,你即可以使用UBS接口連接電腦來充電,假如只有iphone沒有電腦,怎么辦呢?蘋果提供了iphone電源適配器??梢允褂眠@個電源適配器充電。這個iphone的電源適配器就是類似我們說的適配器模式。(電源適配器就是把電源變成需要的電壓,也就是適配器的作用是使得一個東西適合另外一個東西。)

       例子2:最典型的例子就是很多功能手機,每一種機型都自帶有從電器,有一天自帶充電器壞了,而且市場沒有這類型充電器可買了。怎么辦?萬能充電器就可以解決。這個萬能充電器就是適配器。

2. 問題

 

     你如何避免因外部庫的API改變而帶來的不便?假如你寫了一個庫,你能否提供一種方法允許你軟件的現(xiàn)有用戶進(jìn)行完美地升級,即使你已經(jīng)改變了你的API?為了更好地適宜于你的需要,你應(yīng)該如何改變一個對象的接口?

3. 解決方案

 

        適配器(Adapter)模式為對象提供了一種完全不同的接口。你可以運用適配器(Adapter)來實現(xiàn)一個不同的類的常見接口,同時避免了因升級和拆解客戶代碼所引起的糾紛。

    適配器模式(Adapter Pattern),把一個類的接口變換成客戶端所期待的另一種接口, Adapter模式使原本因接口不匹配(或者不兼容)而無法在一起工作的兩個類能夠在一起工作。又稱為轉(zhuǎn)換器模式、變壓器模式、包裝(Wrapper)器模式(把已有的一些類包裝起來,使之能有滿足需要的接口)。
     考慮一下當(dāng)(不是假設(shè)!)一個第三方庫的API改變將會發(fā)生什么。過去你只能是咬緊牙關(guān)修改所有的客戶代碼,而情況往往還不那么簡單。你可能正從事一項新的項目,它要用到新版本的庫所帶來的特性,但你已經(jīng)擁有許多舊的應(yīng)用程序,并且它們與以前舊版本的庫交互運行地很好。你將無法證明這些新特性的利用價值,如果這次升級意味著將要涉及到其它應(yīng)用程序的客戶代碼。

4. 分類

 

共有兩類適配器模式:1.類的適配器模式(采用繼承實現(xiàn))2.對象適配器(采用對象組合方式實現(xiàn))

1)類適配器模式    ——適配器繼承自已實現(xiàn)的類(一般多重繼承)。

Adapter與Adaptee是繼承關(guān)系

1、用一個具體的Adapter類和Target進(jìn)行匹配。結(jié)果是當(dāng)我們想要一個匹配一個類以及所有它的子類時,類Adapter將不能勝任工作
2、使得Adapter可以重定義Adaptee的部分行為,因為Adapter是Adaptee的一個子集
3、僅僅引入一個對象,并不需要額外的指針以間接取得adaptee
2)對象適配器模式—— 適配器容納一個它包裹的類的實例。在這種情況下,適配器調(diào)用被包裹對象的物理實體。

Adapter與Adaptee是委托關(guān)系

1、允許一個Adapter與多個Adaptee同時工作。Adapter也可以一次給所有的Adaptee添加功能
2、使用重定義Adaptee的行為比較困難
無論哪種適配器,它的宗旨都是:保留現(xiàn)有類所提供的服務(wù),向客戶提供接口,以滿足客戶的期望。
即在不改變原有系統(tǒng)的基礎(chǔ)上,提供新的接口服務(wù)。

5. 適用性

 

以下情況使用Adapter模式:

1 • 你想使用一個已經(jīng)存在的類,而它的接口不符合你的需求。
2 • 你想創(chuàng)建一個可以復(fù)用的類,該類可以與其他不相關(guān)的類或不可預(yù)見的類(即那些接口可能不一定兼容的類)協(xié)同工作。
3 •(僅適用于對象Adapter)你想使用一些已經(jīng)存在的子類,但是不可能對每一個都進(jìn)行子類化以匹配它們的接口。對象適配器可以適配它的父類接口。即僅僅引入一個對象,并不需要額外的指針以間接取得adaptee。

6. 結(jié)構(gòu)

 

類適配器使用多重繼承對一個接口與另一個接口進(jìn)行匹配,如下圖所示:

PHP設(shè)計模式(五)適配器模式Adapter實例詳解【結(jié)構(gòu)型】

對象匹配器依賴于對象組合,如下圖所示:

PHP設(shè)計模式(五)適配器模式Adapter實例詳解【結(jié)構(gòu)型】

7. 構(gòu)建模式的組成

 

•目標(biāo)角色(Target):— 定義Client使用的與特定領(lǐng)域相關(guān)的接口。
• 客戶角色(Client):與符合Target接口的對象協(xié)同。
• 被適配橘色(Adaptee):定義一個已經(jīng)存在并已經(jīng)使用的接口,這個接口需要適配。
• 適配器角色(Adapte) :適配器模式的核心。它將對被適配Adaptee角色已有的接口轉(zhuǎn)換為目標(biāo)角色Target匹配的接口。對Adaptee的接口與Target接口進(jìn)行適配.

8. 效果

 

類適配器和對象適配器有不同的權(quán)衡。

類適配器

• 用一個具體的Adapter類對Adaptee和Target進(jìn)行匹配。結(jié)果是當(dāng)我們想要匹配一個類以及所有它的子類時,類Adapter將不能勝任工作。
• 使得Adapter可以重定義Adaptee的部分行為,因為Adapter是Adaptee的一個子類。
• 僅僅引入了一個對象,并不需要額外的指針以間接得到 Adaptee。

對象適配器則

• 允許一個Adapter與多個Adaptee—即Adaptee本身以及它的所有子類(如果有子類的話)—同時工作。Adapter也可以一次給所有的Adaptee添加功能。
• 使得重定義Adaptee的行為比較困難。這就需要生成Adaptee的子類并且使得Adapter引用這個子類而不是引用Adaptee本身。

使用Adapter模式時需要考慮的其他一些因素有:

1) Adapter的匹配程度 對Adaptee的接口與Target的接口進(jìn)行匹配的工作量各個Adapter可能不一樣。工作范圍可能是,從簡單的接口轉(zhuǎn)換(例如改變操作名 )到支持完全不同的操作集合。Adapter的工作量取決于Target接口與Adaptee接口的相似程度
2) 可插入的Adapter   當(dāng)其他的類使用一個類時,如果所需的假定條件越少,這個類就更具可復(fù)用性。如果將接口匹配構(gòu)建為一個類,
就不需要假定對其他的類可見的是一個相同的接口。也就是說,接口匹配使得我們可以將自己的類加入到一些現(xiàn)有的系統(tǒng)中去,
而這些系統(tǒng)對這個類的接口可能會有所不同。 
3) 使用雙向適配器提供透明操作 使用適配器的一個潛在問題是,它們不對所有的客戶都透明。被適配的對象不再兼容 Adaptee的接口,
因此并不是所有 Adaptee對象可以被使用的地方它都可以被使用。雙向適配器提供了這樣的透明性。
在兩個不同的客戶需要用不同的方式查看同一個對象時,雙向適配器尤其有用。

9. 實現(xiàn)

 

類適配器使用的是繼承

讓我們看看當(dāng)API改變時,如何保護(hù)應(yīng)用程序不受影響。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
/**
 * 類適配器模式
 * @author guisu
 *
 */
 
/**
 * 目標(biāo)角色
 * @version 1.0
 */
class Target {
 
  /**
   * 這個方法將來有可能改進(jìn)
   */
  public function hello(){
   echo 'Hello ';
  }
 
  /**
   * 目標(biāo)點
   */
  public function world(){
   echo 'world';
  }
}
 
/**
 * Client 程序
 *
 */
class Client {
 
  /**
   * Main program.
   */
  public static function main() {
    $Target = new Target();
    $Target->hello();
    $Target->world();
 
  }
 
}
Client::main();
?>

我們Target已經(jīng)明確指出hello()方法會在未來的版本中改進(jìn),甚至不被支持或者淘汰。接下來,現(xiàn)在假設(shè)第二版的Target已經(jīng)發(fā)布。一個全新的greet()方法代替了hello()。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
/**
 * 類適配器模式
 * @author guisu
 *
 */
 
/**
 * 目標(biāo)角色
 * @version 2.0
 */
class Target {
 
  /**
   * 這個方法將來有可能繼續(xù)改進(jìn)
   */
  public function greet(){
   echo 'Greet ';
  }
 
  /**
   * 目標(biāo)點
   */
  public function world(){
   echo 'world';
  }
}

如果我們繼續(xù)使用原來的client代碼,肯定會報錯,找不到hello方法。

針對API“升級”的解決辦法就是創(chuàng)建一個適配器(Adapter)。

類適配器使用的是繼承:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php
/**
 * 類適配器模式
 * @author guisu
 *
 */
 
/**
 * 目標(biāo)角色
 * @version 2.0
 */
interface Target {
 
  /**
   * 源類的方法:這個方法將來有可能繼續(xù)改進(jìn)
   */
  public function hello();
 
  /**
   * 目標(biāo)點
   */
  public function world();
}
 
/**
 * 源角色:被適配的角色
 */
class Adaptee {
 /**
   * 源類含有的方法
   */
  public function world() {
    echo ' world <br />';
  }
 
  /**
   * 加入新的方法
   */
  public function greet() {
    echo ' Greet ';
  }
}
 
/**
 * 類適配器角色
 */
class Adapter extends Adaptee implements Target {
 
  /**
   * 源類中沒有world方法,在此補充
   */
  public function hello() {
    parent::greet();
  }
 
}
/**
 * 客戶端程序
 *
 */
class Client {
 
  /**
   * Main program.
   */
  public static function main() {
    $adapter = new Adapter();
    $adapter->hello();
    $adapter->world();
  }
}
Client::main();
?>

對象適配器使用的是委派

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<?php
/**
 * 類適配器模式
 * @author guisu
 *
 */
 
/**
 * 目標(biāo)角色
 * @version 2.0
 */
interface Target {
 
  /**
   * 源類的方法:這個方法將來有可能繼續(xù)改進(jìn)
   */
  public function hello();
 
  /**
   * 目標(biāo)點
   */
  public function world();
}
 
/**
 * 源角色:被適配的角色
 */
class Adaptee {
 /**
   * 源類含有的方法
   */
  public function world() {
    echo ' world <br />';
  }
 
  /**
   * 加入新的方法
   */
  public function greet() {
    echo ' Greet ';
  }
}
 
/**
 * 類適配器角色
 */
class Adapter implements Target {
 
 private $_adaptee;
 /**
  * construct
  *
  * @param Adaptee $adaptee
  */
  public function __construct(Adaptee $adaptee) {
    $this->_adaptee = $adaptee;
  }
 
  /**
   * 源類中沒有world方法,在此補充
   */
  public function hello() {
    $this->_adaptee->greet();
  }
 
  /**
   * 源類中沒有world方法,在此補充
   */
  public function world() {
    $this->_adaptee->world();
  }
}
/**
 * 客戶端程序
 *
 */
class Client {
 
  /**
   * Main program.
   */
  public static function main() {
   $adaptee = new Adaptee();
    $adapter = new Adapter($adaptee);
    $adapter->hello();
    $adapter->world();
  }
}
Client::main();
?>

如例中代碼所示,你可以運用適配器(Adapter)模式來避免因外部庫改變所帶來的不便——倘若向上兼容。作為某個庫的開發(fā)者,你應(yīng)該獨立編寫適配器,使你的用戶更簡便地使用新版本的庫,而不用去修改他們現(xiàn)有的全部代碼。

     GoF書中提出的適配器(Adapter)模式更傾向于運用繼承而不是組成。這在強類型語言中是有利的,因為適配器(Adapter)事實上是一個目標(biāo)類的子類,因而能更好地與類中方法相結(jié)合。

了更好的靈活性,我個人比較傾向于組成的方法(特別是在結(jié)合了依賴性倒置的情況下);盡管如此,繼承的方法提供兩種版本的接口,或許在你的實際運用中反而是一個提高靈活性的關(guān)鍵。

10.適配器模式與其它相關(guān)模式

 

橋梁模式(bridge模式):橋梁模式與對象適配器類似,但是橋梁模式的出發(fā)點不同:橋梁模式目的是將接口部分和實現(xiàn)部分分離,從而對它們可以較為容易也相對獨立的加以改變。而對象適配器模式則意味著改變一個已有對象的接口

裝飾器模式(decorator模式):裝飾模式增強了其他對象的功能而同時又不改變它的接口。因此裝飾模式對應(yīng)用的透明性比適配器更好。結(jié)果是decorator模式支持遞歸組合,而純粹使用適配器是不可能實現(xiàn)這一點的。

Facade(外觀模式):適配器模式的重點是改變一個單獨類的API。Facade的目的是給由許多對象構(gòu)成的整個子系統(tǒng),提供更為簡潔的接口。而適配器模式就是封裝一個單獨類,適配器模式經(jīng)常用在需要第三方API協(xié)同工作的場合,設(shè)法把你的代碼與第三方庫隔離開來。

適配器模式與外觀模式都是對現(xiàn)相存系統(tǒng)的封裝。但這兩種模式的意圖完全不同,前者使現(xiàn)存系統(tǒng)與正在設(shè)計的系統(tǒng)協(xié)同工作而后者則為現(xiàn)存系統(tǒng)提供一個更為方便的訪問接口。簡單地說,適配器模式為事后設(shè)計,而外觀模式則必須事前設(shè)計,因為系統(tǒng)依靠于外觀。總之,適配器模式?jīng)]有引入新的接口,而外觀模式則定義了一個全新的接口。

代理模式(Proxy )在不改變它的接口的條件下,為另一個對象定義了一個代理。

裝飾者模式,適配器模式,外觀模式三者之間的區(qū)別:

裝飾者模式的話,它并不會改變接口,而是將一個一個的接口進(jìn)行裝飾,也就是添加新的功能。

適配器模式是將一個接口通過適配來間接轉(zhuǎn)換為另一個接口。

外觀模式的話,其主要是提供一個整潔的一致的接口給客戶端。

希望本文所述對大家PHP程序設(shè)計有所幫助。

原文鏈接:https://blog.csdn.net/hguisu/article/details/7527842

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲 欧美 日韩 在线 | 日本精品一区 | 亚洲精品国产第一综合99久久 | 国产在线观看一区二区三区 | 欧美日韩精品一区二区三区四区 | 日韩中文字幕在线观看视频 | 人人添人人添 | 久久综合久久久 | 夜夜操比| 北条麻妃99精品青青久久 | 婷婷综合网 | 欧美精品国产精品 | 日韩av中文| 一级黄色大片在线观看 | 欧州一区二区三区 | 亚洲一区二区在线 | 日韩精品一区二区三区视频播放 | 黄色小视频在线观看 | 在线看国产 | 黄色国产视频 | 欧美激情一区二区三级高清视频 | 激情综合五月 | 伊人操操 | 国产精品一二三区视频 | 中文字幕一区二区三区四区不卡 | 国产高清不卡在线 | 亚洲欧洲精品一区二区 | 久久久久无码国产精品一区 | 亚洲视频中文字幕在线观看 | 欧美精品久久久 | 久国产精品视频 | 久久99久久99精品免观看粉嫩 | 国产精品美女久久久久久免费 | 亚洲精品在线免费看 | 天天摸天天做天天爽 | 正在播放国产一区 | 999精品视频 | 成人精品国产 | 欧美一区免费 | 欧美精品一区二区三区在线 | 精品久久久久国产 |