設計模式之適配器模式(Adapter Pattern)C++實現

來源:互聯網
上載者:User

標籤:適配器模式   c++實現   adapterpattern   

適配器模式(Adapter Pattern)是作為兩個不相容的介面之間的橋樑。這種類型的設計模式屬於結構型模式,它結合了兩個獨立介面的功能。

意圖:將一個類的介面轉換成客戶希望的另外一個介面。適配器模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。

主要解決:主要解決在軟體系統中,常常要將一些"現存的對象"放到新的環境中,而新環境要求的介面是現對象不能滿足的。

何時使用: 1、系統需要使用現有的類,而此類的介面不符合系統的需要。 2、想要建立一個可以重複使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作,這些源類不一定有一致的介面。 3、通過介面轉換,將一個類插入另一個類系中。(比如老虎和飛禽,現在多了一個飛虎,在不增加實體的需求下,增加一個適配器,在裡麵包容一個虎對象,實現飛的介面。)

如何解決:繼承或依賴(推薦)。

優點: 1、可以讓任何兩個沒有關聯的類一起運行。 2、提高了類的複用。 3、增加了類的透明度。 4、靈活性好。

缺點: 1、過多地使用適配器,會讓系統非常零亂,不易整體進行把握。比如,明明看到調用的是 A 介面,其實內部被適配成了 B 介面的實現,一個系統如果太多出現這種情況,無異於一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統進行重構。 2.由於 JAVA 至多繼承一個類,所以至多隻能適配一個適配者類,而且目標類必須是抽象類別。

使用情境:有動機地修改一個正常啟動並執行系統的介面,這時應該考慮使用適配器模式。

注意事項:適配器不是在詳細設計時添加的,而是解決正在服役的項目的問題。

實現:

我們有一個 MediaPlayer 介面和一個實現了 MediaPlayer 介面的實體類 AudioPlayer。預設情況下,AudioPlayer 可以播放 mp3 格式的音頻檔案。

我們還有另一個介面 AdvancedMediaPlayer 和實現了 AdvancedMediaPlayer 介面的實體類。該類可以播放 vlc 和 mp4 格式的檔案。

我們想要讓 AudioPlayer 播放其他格式的音頻檔案。為了實現這個功能,我們需要建立一個實現了 MediaPlayer 介面的適配器類MediaAdapter,並使用 AdvancedMediaPlayer 對象來播放所需的格式。

AudioPlayer 使用適配器類 MediaAdapter 傳遞所需的音訊類型,不需要知道能播放所需格式音訊實際類。

代碼:

步驟 1為媒體播放器和更進階的媒體播放器建立介面。

MediaPlayer.h

#pragma once/*MediaPlayer.h*/#include "stdafx.h"class MediaPlayer{public:virtual void play(string& audioType, string& filename) = 0;virtual ~MediaPlayer(){cout<< "this is mediaplayer desconstructor." << endl;}};
AdvanceMediaPlayer.h
#pragma once/*AdvanceMediaPlayer.h*/#include "stdafx.h"class AdvanceMediaPlayer{public://這裡構造要麼不寫,要麼就寫為內聯空實現的形式AdvanceMediaPlayer(){}//AdvanceMediaPlayer();virtual ~AdvanceMediaPlayer(){}virtual void playVcl(string& filename) = 0;virtual void playMp4(string& filename) = 0;};

步驟 2

建立實現了 AdvancedMediaPlayer 介面的實體類。

Mp4Player.h及其實現

#pragma once#include "advancemediaplayer.h"class Mp4Player :public AdvanceMediaPlayer{public:Mp4Player(void);~Mp4Player(void);virtual void playVcl(string& filename);virtual void playMp4(string& filename);};void Mp4Player::playVcl(string& filename){//null}void Mp4Player::playMp4(string& filename){cout <<"playing mp4 media file.name"<< filename << endl;}
VclPlayer.h及實現
#pragma once#include "advancemediaplayer.h"class VclPlayer :public AdvanceMediaPlayer{public:VclPlayer(void);~VclPlayer(void);virtual void playVcl(string& filename);virtual void playMp4(string& filename);};void VclPlayer::playVcl(string& filename){cout <<"playing vcl media file.name"<< filename << endl;}void VclPlayer::playMp4(string& filename){//null}

步驟 3

建立實現了 MediaPlayer 介面的適配器類。

AdapterMediaPlayer.h和AdapterMediaPlayer.cpp

#pragma once#include "mediaplayer.h"#include "AdvanceMediaPlayer.h"class AdapterMediaPlayer :public MediaPlayer{public:AdapterMediaPlayer(string& audioType);~AdapterMediaPlayer(void);virtual void play(string& audioType, string& filename);private:AdvanceMediaPlayer* advanceMusicPlayer;};#include "StdAfx.h"#include "AdapterMediaPlayer.h"#include "Mp4Player.h"#include "VclPlayer.h"AdapterMediaPlayer::AdapterMediaPlayer(string& audioType){if (audioType.compare("vcl") == 0){this->advanceMusicPlayer = new VclPlayer();}else if (audioType.compare("mp4") == 0){this->advanceMusicPlayer =  new Mp4Player();}}AdapterMediaPlayer::~AdapterMediaPlayer(void){if (advanceMusicPlayer != NULL){delete advanceMusicPlayer;advanceMusicPlayer = NULL;}}void AdapterMediaPlayer::play(string& audioType, string& filename){if (audioType.compare("vcl") == 0){this->advanceMusicPlayer->playVcl(filename);}else if (audioType.compare("mp4") == 0){this->advanceMusicPlayer->playMp4(filename);}}

步驟 4

建立實現了 MediaPlayer 介面的實體類。

AudioPlayer.h和AudioPlayer.cpp

#pragma once#include "mediaplayer.h"#include "AdapterMediaPlayer.h"class AudioPlayer :public MediaPlayer{public:AudioPlayer(void);~AudioPlayer(void);void play(string& audioType, string& filename);private: AdapterMediaPlayer* mediaAdapter;};#include "StdAfx.h"#include "AudioPlayer.h"AudioPlayer::AudioPlayer(void){mediaAdapter = NULL;}AudioPlayer::~AudioPlayer(void){if (mediaAdapter != NULL){delete mediaAdapter ;mediaAdapter =NULL;}}void AudioPlayer::play(string& audioType, string& filename){if (audioType.compare("mp3") == 0){cout << "playing mp3 file.name:" << filename << endl;}else if (!audioType.compare("vcl") || !audioType.compare("mp4")){//這裡容易出現了記憶體泄露。mediaAdapter = new AdapterMediaPlayer(audioType);mediaAdapter->play(audioType,filename);}else{cout << "Invalid media." << audioType << "and this format not support." << endl;}if (mediaAdapter != NULL){delete mediaAdapter ;mediaAdapter =NULL;}//指標釋放原則,構造new析構delete,函數中new函數中delete,最後析構還有保險delete。}

步驟 5

使用 AudioPlayer 來播放不同類型的音頻格式。

#include "stdafx.h"#include "AudioPlayer.h"int _tmain(int argc, _TCHAR* argv[]){AudioPlayer* audioPlayer = new AudioPlayer();audioPlayer->play(string("mp3"), string("beyond the horizon.mp3"));audioPlayer->play(string("mp4"), string("alone.mp4"));audioPlayer->play(string("vcl"), string("far far away.vcl"));audioPlayer->play(string("avi"), string("mind me.avi"));delete audioPlayer;audioPlayer = NULL;system("pause");return 0;}

最後,代碼只是參考,最重要的還是思想。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

設計模式之適配器模式(Adapter Pattern)C++實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.