1. 程式人生 > >Java設計模式面試題2則

Java設計模式面試題2則

【題目-1Windows Media PlayerRealPlayer是常用的媒體播放器,它們的API結構和呼叫方法非常不同,現在你的應用需要同時支援呼叫這2種播放器的API。你要怎麼設計?

【分析】明顯應該採用Adapter模式,將播放器的同類型API進行分類,對於播放器某一些同類型的API(比如畫面調節),定義MediaPlayerClassARealPlayerClassA都實現了IMediaA介面MediaPlayerClassA呼叫MediaPlayerAPIs來實現IMediaA介面定義的功能;RealPlayerClassA則呼叫RealPlayer APIs

對另外一些類似的

API(比如聲音調節),定義MediaPlayerClassBRealPlayerClassB都實現IMediaB介面;

依次類推……

  在建立這些同類型的MediaPlayerClassARealPlayerClassAMediaPlayerClassBRealPlayerClassB……的時候考慮使用工廠方法,一類API定義一個工廠類,這其實是抽象工廠方法。定義介面MediaFactoryAPI型別,MediaPlayerFactoryRealPlayerFactory實現該介面,MediaPlayerFactory建立MediaPlayer產品族,即MediaPlayerClassA

MediaPlayerClassB……;RealPlayerFactory利用建立RealPlayer產品族,即RealPlayerClassARealPlayerClassB……。另外,定義一個AllFactory類採用靜態方法分別生成MediaPlayerFactoryRealPlayerFactory

  所以總的模式是“Adapter+Factory”。左邊是介面卡模式,右邊是工廠模式(抱歉不太會畫UM,線上畫圖工具

  

<span style="font-weight: normal;">IMediaA iMediaA=AllFactory.createMediaPlayFactory().produceClassA();
        iMediaA.fixPicture();
        IMediaA iMediaA2=
AllFactory.createRealPlayerFactory().produceClassA();
        iMediaA2.fixPicture();</span>


……

Java模擬:

比如Windows Media PlayerRealPlayer各自有一類調整畫面的API,標記為第A類:

<span style="font-weight: normal;">/** 
 * 建立時間:2014年9月9日 下午4:39:29 
 * 專案名稱:Test 
 * @author Cao Yanfeng 
 * @since JDK 1.6.0_21 
 * 類說明: 
 */
public class MediaPlayer {
    public void pictureAdjust() {
        System.out.println("picure is adjusting……");
    }
 
}
/** 
 * 建立時間:2014年9月9日 下午4:39:41 
 * 專案名稱:Test 
 * @author Cao Yanfeng 
 * @since JDK 1.6.0_21 
 * 類說明: 
 */
/**
 * @author Yanfeng Cao
 *
 */
public class RealPlayer {
    public void adjustPicture() {
        System.out.println("adjusting picure……");
    }
 
}</span>
<span style="font-weight: normal;">/** 
 * 建立時間:2014年9月9日 下午4:42:58 
 * 專案名稱:Test 
 * @author Cao Yanfeng 
 * @since JDK 1.6.0_21 
 * 類說明: 
 */
public interface IMediaA {
    public void fixPicture();
 
}</span>

第二步:根據Adapter模式,生成我自己的API

<span style="font-weight: normal;">/** 
 * 建立時間:2014年9月9日 下午4:38:54 
 * 專案名稱:Test 
 * @author Cao Yanfeng 
 * @since JDK 1.6.0_21 
 * 類說明: 物件的介面卡模式
 */
public class MediaPlayerClassA implements IMediaA{
    private MediaPlayer mediaPlayer;
    /**
     *
     */
    public MediaPlayerClassA(MediaPlayer mediaPlayer) {
        // TODO Auto-generated constructor stub
        this.mediaPlayer=mediaPlayer;
    }
    @Override
    public void fixPicture() {
        // TODO Auto-generated method stub
        mediaPlayer.pictureAdjust();
    }
 
}
/** 
 * 建立時間:2014年9月9日 下午4:39:16 
 * 專案名稱:Test 
 * @author Cao Yanfeng 
 * @since JDK 1.6.0_21 
 * 類說明: 
 */
public class RealPlayerClassA implements IMediaA{
    private RealPlayer realPlayer;
    /**
     *
     */
    public RealPlayerClassA(RealPlayer realPlayer) {
        // TODO Auto-generated constructor stub
        this.realPlayer=realPlayer;
    }
 
    @Override
    public void fixPicture() {
        // TODO Auto-generated method stub
        realPlayer.adjustPicture();
    }
 
}</span>

第三步:生成產生以上兩個類的工廠介面和工廠類,這是抽象工廠模式

<span style="font-weight: normal;">/** 
 * 建立時間:2014年9月9日 下午4:55:28 
 * 專案名稱:Test 
 * @author Cao Yanfeng 
 * @since JDK 1.6.0_21 
 * 類說明: 
 */
public interface MediaFactory {
    public IMediaA produceClassA();
 
}
/** 
 * 建立時間:2014年9月9日 下午4:57:14 
 * 專案名稱:Test 
 * @author Cao Yanfeng 
 * @since JDK 1.6.0_21 
 * 類說明: 抽象工廠模式
 */
public class MediaPlayFactory implements MediaFactory {
 
    /* (non-Javadoc)
     * @see cn.geosis.mode.Factory#produceClassA()
     */
    @Override
    public IMediaA produceClassA() {
        // TODO Auto-generated method stub
        return new MediaPlayerClassA(new MediaPlayer());
    }
}
/** 
 * 建立時間:2014年9月9日 下午4:58:38 
 * 專案名稱:Test 
 * @author Cao Yanfeng 
 * @since JDK 1.6.0_21 
 * 類說明: 抽象工廠模式
 */
public class RealPlayerFactory implements MediaFactory {
 
    /* (non-Javadoc)
     * @see cn.geosis.mode.Factory#produceClassA()
     */
    @Override
    public IMediaA produceClassA() {
        // TODO Auto-generated method stub
        return new RealPlayerClassA(new RealPlayer());
    }
}</span>

第四步:用一個靜態工廠模式生成以上兩個工廠類

<span style="font-weight: normal;">/** 
 * 建立時間:2014年9月9日 下午5:04:08 
 * 專案名稱:Test 
 * @author Cao Yanfeng 
 * @since JDK 1.6.0_21 
 * 類說明: 靜態工廠模式
 */
public  class AllFactory{
    public static MediaPlayFactory createMediaPlayFactory() {
        return new MediaPlayFactory();
    }
    public static RealPlayerFactory createRealPlayerFactory() {
        return new RealPlayerFactory();
    }
}</span>

測試:

<span style="font-weight: normal;">/** 
 * 建立時間:2014年9月9日 下午5:08:53 
 * 專案名稱:Test 
 * @author Cao Yanfeng 
 * @since JDK 1.6.0_21 
 * 類說明: 
 */
public class Test {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        IMediaA iMediaA=AllFactory.createMediaPlayFactory().produceClassA();
        iMediaA.fixPicture();
        IMediaA iMediaA2=AllFactory.createRealPlayerFactory().produceClassA();
        iMediaA2.fixPicture();
    }
 
}</span>

****************************************************************

  對於B類的APIs,例如調整音量,需要定義介面ImediaB,採用介面卡模式生成MediaPlayerClassBRealPlayerClassB在以上的工廠介面MediaFactory中加入public IMediaB produceClassB(),在以上的兩個工廠方法中加入public IMediaB produceClassB()方法即完成了BAPIs的新增,呼叫過程:

<span style="font-weight: normal;"> IMediaB iMediaB=AllFactory.createMediaPlayFactory().produceClassB();
        iMediaB.fixVolume();</span>

【題目—2現在有一種空調,它支援3種模式:Hot AirCool Air DoNothing。例如,當選擇Hot Air模式時,再選擇溫度為20度,空調將輸送熱風;選擇 Cool Air模式,溫度設定為20度時,將輸送冷風;在選擇DoNothing模式時,空調什麼都不做。你將考慮如何為空調設計應用程式?如果將來空調需要增加支援新的模式呢?

【分析】參考中說是用享元模式,應該是不合適的,我認為應該用狀態模式(State)。