Java设计模式面试题2则

  Java中有23中设计模式,重要的包括:工厂方法、抽象工厂方法、单例模式、建造者模式、适配器模式、代理模式、桥接模式、策略模式、观察者模式。参考http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html给了很简明的介绍。

【题目-1Windows Media PlayerRealPlayer是常用的媒体播放器,它们的API结构和调用方法非常不同,现在你的应用需要同时支持调用这2种播放器的API。你要怎么设计?

【分析】明显应该采用Adapter模式,将播放器的同类型API进行分类,对于播放器某一些同类型的API(比如画面调节),定义MediaPlayerClassARealPlayerClassA都实现了IMediaA接口MediaPlayerClassA调用MediaPlayerAPIs来实现IMediaA接口定义的功能;RealPlayerClassA则调用RealPlayer APIs

   对另外一些类似的API(比如声音调节),定义MediaPlayerClassBRealPlayerClassB都实现IMediaB接口;

依次类推……

  在创建这些同类型的MediaPlayerClassARealPlayerClassAMediaPlayerClassBRealPlayerClassB……的时候考虑使用工厂方法,一类API定义一个工厂类,这其实是抽象工厂方法。定义接口MediaFactory该接口定义所有的API类型,MediaPlayerFactoryRealPlayerFactory实现该接口,MediaPlayerFactory创建MediaPlayer产品族,即MediaPlayerClassAMediaPlayerClassB……;RealPlayerFactory利用创建RealPlayer产品族,即RealPlayerClassARealPlayerClassB……。另外,定义一个AllFactory类采用静态方法分别生成MediaPlayerFactoryRealPlayerFactory

   

  所以总的模式是“Adapter+Factory”。左边是适配器模式,右边是工厂模式(抱歉不太会画UM,在线画图工具http://www.genmymodel.com/cn/

  

<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>


第一步:设计我自己的第AAPI的接口IMediaA

<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模式时,空调什么都不做。 你将考虑如何为空调设计应用程序?如果将来空调需要增加支持新的模式呢?

参考:http://www.cnblogs.com/Binhua-Liu/archive/2010/12/23/1914935.html

【分析】参考中说是用享元模式,应该是不合适的,我认为应该用状态模式(State)。


  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值