1. 程式人生 > >介面卡、裝飾者、代理模式對比

介面卡、裝飾者、代理模式對比

一、介面卡的基本概念

1、定義:
將一個介面轉換為另一個客戶期望的介面。

2、應用場景:
你想使用一個已經存在的類,而它的介面不符合你的需求。 類似於一個轉介面,將電源線的介面轉成你電腦可用的介面。

3、類圖:
這裡寫圖片描述
* Target:期待的目標介面
* Adaptee:原來需要轉換的目標
* Adapter:介面卡角色。目的是將原來的目標轉換成客戶期望的目標

二、例項

一個mp4播放器可以播放mp4,一個mp3播放器可以播放mp3,如果想在mp3中播放mp4格式的檔案。

1、Target: 期待轉成MP3

public interface IMp3Player
{
/** * 播放MP3 * @param fileName */ void playMp3(String fileName); }
public class MyMp3Player implements IMp3Player{
    @Override
    public void playMp3(String fileName) {
        System.out.println("正在播放mp3:"+fileName);
    }
}

2、Adaptee 原來的檔案mp4

public interface IMp4Player
{
/** * 播放mp4 * @param fileName */ void playMp4(String fileName); /** * 獲取到檔名 * @return */ String getFileName(); }
public class MyMp4Player implements IMp4Player{
    public String mFileName;

    @Override
    public void playMp4(String fileName) {
        this
.mFileName = fileName; System.out.println("正在播放mp4:"+fileName); } @Override public String getFileName() { return mFileName; } }

3、Adapter 一個格式轉換器

public interface IMediaAdapter {
    /**
     * 檔案轉換
     */
    void conver();
}
public class MyMediaAdapter implements IMediaAdapter{
    private IMp4Player mIMp4Player;
    private IMp3Player mMp3Player;

    public MyMediaAdapter(IMp4Player mp4Player, IMp3Player mp3Player){
        this.mIMp4Player = mp4Player;
        this.mMp3Player = mp3Player;
    }

    @Override
    public void conver() {
        String fileName = mIMp4Player.getFileName();
        this.mMp3Player.playMp3(fileName.replace("mp4","mp3"));
    }
}

4、使用:

public class AdapterTest {

    public static void main(String[] args){
        //建立MP4,並播放
        IMp4Player mp4Player = new MyMp4Player();
        mp4Player.playMp4("my.mp4");
        //建立mp3
        IMp3Player mp3Player = new MyMp3Player();
        //通過介面卡將mp4的檔案轉換,並在mp3中播放
        IMediaAdapter adapter = new MyMediaAdapter(mp4Player, mp3Player);
        adapter.conver();
    }
}

這裡寫圖片描述

三、介面卡、裝飾者、代理模式對比:

1、裝飾模式和代理模式的對比:

相同點:
* 代理物件和被代理物件需要繼承相同的抽象類或者實現相同的介面
* 裝飾物件和被裝飾物件需要繼承相同的抽象類或者實現相同的介面
不同點:
* 代理物件的主要作用是控制被代理物件的訪問。
* 裝飾物件的主要作用是增強被裝飾物件的功能。

舉例:

public interface IPerson {
    /**
     * 睡覺
     */
    void sleep();
}

被裝飾者(被代理類):

public class Son implements IPerson {
    @Override
    public void sleep() {
        System.out.println("兒子去睡覺了");
    }
}

代理類:

public class Parent implements IPerson{
    private IPerson mPerson;
    //工作是否完成
    private boolean mFinishWork;

    public Parent(IPerson person){
        this.mPerson = person;
    }


    public void setFinishWork(boolean finishWork){
        mFinishWork = finishWork;
    }

    @Override
    public void sleep() {
        //控制了被代理類的方法呼叫
        if (mFinishWork) {
            mPerson.sleep();
        }
    }
}

裝飾者:

public class Parent implements IPerson{
    private IPerson mPerson;

    public Parent(IPerson person){
        this.mPerson = person;
    }

    @Override
    public void sleep() {
        //多了吃飯的功能
        System.out.println("先吃飯");
        mPerson.sleep();
    }
}

2、裝飾者和介面卡模式對比

相同點:
* 都是對某個物件進行包裝
不同點:
* 裝飾者包裝的是自己的同類,相同的介面或者父類
* 介面卡包裝的是不同型別的物件,然後將其偽裝成自己的同類。