Java中有23中设计模式,重要的包括:工厂方法、抽象工厂方法、单例模式、建造者模式、适配器模式、代理模式、桥接模式、策略模式、观察者模式。参考http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html给了很简明的介绍。
【题目-1】Windows Media Player和RealPlayer是常用的媒体播放器,它们的API结构和调用方法非常不同,现在你的应用需要同时支持调用这2种播放器的API。你要怎么设计?
【分析】明显应该采用Adapter模式,将播放器的同类型API进行分类,对于播放器某一些同类型的API(比如画面调节),定义MediaPlayerClassA和RealPlayerClassA都实现了IMediaA接口。MediaPlayerClassA调用MediaPlayer的APIs来实现IMediaA接口定义的功能;RealPlayerClassA则调用RealPlayer APIs。
对另外一些类似的API(比如声音调节),定义MediaPlayerClassB和RealPlayerClassB都实现IMediaB接口;
依次类推……
在创建这些同类型的MediaPlayerClassA和RealPlayerClassA,MediaPlayerClassB和RealPlayerClassB……的时候考虑使用工厂方法,一类API定义一个工厂类,这其实是抽象工厂方法。定义接口MediaFactory,该接口定义所有的API类型,MediaPlayerFactory和RealPlayerFactory实现该接口,MediaPlayerFactory创建MediaPlayer产品族,即MediaPlayerClassA、MediaPlayerClassB……;RealPlayerFactory利用创建RealPlayer产品族,即RealPlayerClassA、RealPlayerClassB……。另外,定义一个AllFactory类采用静态方法分别生成MediaPlayerFactory、RealPlayerFactory。
所以总的模式是“Adapter+Factory”。左边是适配器模式,右边是工厂模式(抱歉不太会画UM,在线画图工具http://www.genmymodel.com/cn/)
![](https://img-blog.csdn.net/20140909213119562?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQnJpbGxpYW50RWFnbGU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
Java中有23中设计模式,重要的包括:工厂方法、抽象工厂方法、单例模式、建造者模式、适配器模式、代理模式、桥接模式、策略模式、观察者模式。参考http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html给了很简明的介绍。
【题目-1】Windows Media Player和RealPlayer是常用的媒体播放器,它们的API结构和调用方法非常不同,现在你的应用需要同时支持调用这2种播放器的API。你要怎么设计?
【分析】明显应该采用Adapter模式,将播放器的同类型API进行分类,对于播放器某一些同类型的API(比如画面调节),定义MediaPlayerClassA和RealPlayerClassA都实现了IMediaA接口。MediaPlayerClassA调用MediaPlayer的APIs来实现IMediaA接口定义的功能;RealPlayerClassA则调用RealPlayer APIs。
对另外一些类似的API(比如声音调节),定义MediaPlayerClassB和RealPlayerClassB都实现IMediaB接口;
依次类推……
在创建这些同类型的MediaPlayerClassA和RealPlayerClassA,MediaPlayerClassB和RealPlayerClassB……的时候考虑使用工厂方法,一类API定义一个工厂类,这其实是抽象工厂方法。定义接口MediaFactory,该接口定义所有的API类型,MediaPlayerFactory和RealPlayerFactory实现该接口,MediaPlayerFactory创建MediaPlayer产品族,即MediaPlayerClassA、MediaPlayerClassB……;RealPlayerFactory利用创建RealPlayer产品族,即RealPlayerClassA、RealPlayerClassB……。另外,定义一个AllFactory类采用静态方法分别生成MediaPlayerFactory、RealPlayerFactory。
所以总的模式是“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 Player和RealPlayer各自有一类调整画面的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>
第一步:设计我自己的第A类API的接口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>
<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: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日 下午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: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,采用适配器模式生成MediaPlayerClassB和RealPlayerClassB,在以上的工厂接口MediaFactory中加入public IMediaB produceClassB(),在以上的两个工厂方法中加入public IMediaB produceClassB()方法即完成了B类APIs的添加,调用过程:
<span style="font-weight: normal;"> IMediaB iMediaB=AllFactory.createMediaPlayFactory().produceClassB();
iMediaB.fixVolume();</span>
【题目—2】现在有一种空调,它支持3种模式:Hot Air,Cool Air 和DoNothing。例如,当选择Hot Air模式时,再选择温度为20度,空调将输送热风;选择 Cool Air模式,温度设置为20度时,将输送冷风;在选择DoNothing模式时,空调什么都不做。 你将考虑如何为空调设计应用程序?如果将来空调需要增加支持新的模式呢?】
参考:http://www.cnblogs.com/Binhua-Liu/archive/2010/12/23/1914935.html
【分析】参考中说是用享元模式,应该是不合适的,我认为应该用状态模式(State)。
<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,采用适配器模式生成MediaPlayerClassB和RealPlayerClassB,在以上的工厂接口MediaFactory中加入public IMediaB produceClassB(),在以上的两个工厂方法中加入public IMediaB produceClassB()方法即完成了B类APIs的添加,调用过程:
<span style="font-weight: normal;"> IMediaB iMediaB=AllFactory.createMediaPlayFactory().produceClassB();
iMediaB.fixVolume();</span>
【题目—2】现在有一种空调,它支持3种模式:Hot Air,Cool Air 和DoNothing。例如,当选择Hot Air模式时,再选择温度为20度,空调将输送热风;选择 Cool Air模式,温度设置为20度时,将输送冷风;在选择DoNothing模式时,空调什么都不做。 你将考虑如何为空调设计应用程序?如果将来空调需要增加支持新的模式呢?】
参考:http://www.cnblogs.com/Binhua-Liu/archive/2010/12/23/1914935.html
【分析】参考中说是用享元模式,应该是不合适的,我认为应该用状态模式(State)。