设计模式学习--适配器模式(Adapter Pattern)+外观模式(Facade Pattern)
2013年6月21日设计模式学习今天要学习两个设计模式:适配器模式、外观模式
还是老方式,回顾以往的知识
面向对象基础
- 抽象
- 封装
- 多态
- 继承
面向对象原则
- 封装变化
- 多用组合,少用继承
- 针对接口编程,不针对实现编程
- 为交互对象之间的松耦合设计而努力
- 类应该对扩展开发,对修改关闭
- 依赖抽象,不要依赖具体类
- 只和朋友交谈(用来维护设计中的低层解耦)
适配器模式定义
将一个类的接口,转换成客户期望另一个接口。适配器让原本不兼容的类可以合作无间。外观模式定义
提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。到目前为止我们学习的模式
- 策略模式
- 观察者模式
- 装饰者模式
- 工厂模式
- 单件模式
- 命令模式
关于模式的学习
小巫并不打算一口吃一个胖子,不认为一次就能学好设计模式,要做到灵活运用还是需要沉淀的,程序设计是一门艺术,对我来说是这样,我会一直不停的学习,让自己成为真正的高手。关于适配器模式
3个对象要清楚:- 客户 (客户只看到目标接口)
- 适配器 (适配器实现目标接口)
- 被适配者 (所有的请求都委托给被适配器,与适配器组合)
再近一点:用火鸡来冒充鸭子
目标接口package ducks;
/**
*
* @author wwj
* 适配器模式:鸭接口
*/
public interface Duck {
public void quack();//呱呱叫
public void fly();//飞行
}
目标接口具体实现类
package ducks;
/**
*
*@author wwj
*适配器模式:绿头鸭实现类
*
*/
public class MallardDuck implements Duck {
@Override
public void quack() {
System.out.println("Quack");
}
@Override
public void fly() {
System.out.println("I'm flying");
}
}
被适配对象接口
package ducks;
/**
*
* @author wwj
* 火鸡
*/
public interface Turkey {
public void gobble();//咯咯叫
public void fly();//火鸡也会飞,但飞不远
}
被适配对象接口具体实现类
package ducks;
/**
*
* @author wwj
* 火鸡具体实现类
*/
public class WildTurkey implements Turkey {
@Override
public void gobble() {
System.out.println("Gobble gobble");
}
@Override
public void fly() {
System.out.println("I'm flying a short distance");
}
}
适配器
package ducks;
/**
*
* @author wwj
* 适配器类:用火鸡来冒充鸭子
*/
public class TurkeyAdapter implements Duck {
Turkey turkey;//声明你需要适配的引用对象
/**
* 取得需要适配的对象引用,这里通过构造器来取得这个引用
* @param turkey
*/
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
@Override
public void quack() { //实现接口中的方法
turkey.gobble();//用适配对象来转换需要实现的功能
}
@Override
public void fly() {
for(int i = 0; i < 5; i++) {
turkey.fly();
}
}
}
测试一下
package ducks;
public class TurkeyTestDrive {
public static void main(String[] args) {
WildTurkey turkey = new WildTurkey(); //创建一只火鸡
MallardDuck duck = new MallardDuck();//创建一只鸭子
Turkey duckAdpter = new DuckAdapter(duck);//传进一个鸭子去,用来假装为火鸡
//测试鸭子
System.out.println("The Duck says...");
duck.quack();
duck.fly();
//测试火鸡
System.out.println("\nThe Turkey says...");
testTurkey(turkey);
//测试适配器
System.out.println("\nThe duckAdapter says...");
testTurkey(turkey);
}
private static void testTurkey(Turkey turkey) {
turkey.gobble();
turkey.fly();
}
}
适配器模式测试结果The Turkey says...
Gobble gobble
I'm flying a short distance
The Duck says...
Quack
I'm flying
The TurkeyAdapter says...
Gobble gobble
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance
好了,以上就是适配器模式的使用,下面是外观模式
关于外观模式
我们需要明白这个模式的意图是什么:简化接口,把复杂的子系统封装起来,可以使用户更加方便使用功能一个外观模式的例子:家庭电影观赏
构造家庭影院外观package hometheater;
public class HomeTheaterFacade {
//这就是组合,我们会用到的子系统组件全部都在这里
Amplifier amp;
Tuner tuner;
DvdPlayer dvd;
CdPlayer cd;
Projector projector;
TheaterLights lights;
Screen screen;
PopcornPopper popper;
/**
* 外观将子系统每一个组件的引用都传入它的构造器中。然后外观把它们赋值给相应的实例变量
* @param amp
* @param tuner
* @param dvd
* @param cd
* @param projector
* @param lights
* @param screen
* @param popper
*/
public HomeTheaterFacade(Amplifier amp, Tuner tuner, DvdPlayer dvd,
CdPlayer cd, Projector projector, TheaterLights lights,
Screen screen, PopcornPopper popper) {
this.amp = amp;
this.tuner = tuner;
this.dvd = dvd;
this.cd = cd;
this.projector = projector;
this.lights = lights;
this.screen = screen;
this.popper = popper;
}
/**
* 实现简化的接口
* @param movie
*/
public void watchMovie(String movie) {
System.out.println("Get ready to watch a movie...");
popper.on();
popper.pop();
lights.dim(10);
screen.down();
projector.on();
projector.wideScreenMode();
amp.on();
amp.setDvd(dvd);
amp.setSurroundSound();
amp.setVolume(5);
dvd.on();
dvd.play(movie);
}
public void endMovie() {
System.out.println("Shutting movie theater down...");
popper.off();
lights.on();
screen.up();
projector.off();
amp.off();
dvd.stop();
dvd.eject();
dvd.off();
}
public void listenToCd(String cdTitle) {
System.out.println("Get ready for an audiopile experence...");
lights.on();
amp.on();
amp.setVolume(5);
amp.setCd(cd);
amp.setStereoSound();
cd.on();
cd.play(cdTitle);
}
public void endCd() {
System.out.println("Shutting down CD...");
amp.off();
amp.setCd(cd);
cd.eject();
cd.off();
}
public void listenToRadio(double frequency) {
System.out.println("Tuning in the airwaves...");
tuner.on();
tuner.setFrequency(frequency);
amp.on();
amp.setVolume(5);
amp.setTuner(tuner);
}
public void endRadio() {
System.out.println("Shutting down the tuner...");
tuner.off();
amp.off();
}
}
各个子系统类的实现
package hometheater;
public class Amplifier {
String description;
Tuner tuner;
DvdPlayer dvd;
CdPlayer cd;
public Amplifier(String description) {
this.description = description;
}
public void on() {
System.out.println(description + " on");
}
public void off() {
System.out.println(description + " off");
}
public void setStereoSound() {
System.out.println(description + " stereo mode on");
}
public void setSurroundSound() {
System.out.println(description + " surround sound on (5 speakers, 1 subwoofer)");
}
public void setVolume(int level) {
System.out.println(description + " setting volume to " + level);
}
public void setTuner(Tuner tuner) {
System.out.println(description + " setting tuner to " + dvd);
this.tuner = tuner;
}
public void setDvd(DvdPlayer dvd) {
System.out.println(description + " setting DVD player to " + dvd);
this.dvd = dvd;
}
public void setCd(CdPlayer cd) {
System.out.println(description + " setting CD player to " + cd);
this.cd = cd;
}
public String toString() {
return description;
}
}
package hometheater;
public class CdPlayer {
String description;
int currentTrack;
Amplifier amplifier;
String title;
public CdPlayer(String description, Amplifier amplifier) {
this.description = description;
this.amplifier = amplifier;
}
public void on() {
System.out.println(description + " on");
}
public void off() {
System.out.println(description + " off");
}
public void eject() {
title = null;
System.out.println(description + " eject");
}
public void play(String title) {
this.title = title;
currentTrack = 0;
System.out.println(description + " playing \"" + title + "\"");
}
public void play(int track) {
if (title == null) {
System.out.println(description + " can't play track "
+ currentTrack + ", no cd inserted");
} else {
currentTrack = track;
System.out.println(description + " playing track " + currentTrack);
}
}
public void stop() {
currentTrack = 0;
System.out.println(description + " stopped");
}
public void pause() {
System.out.println(description + " paused \"" + title + "\"");
}
public String toString() {
return description;
}
}
package hometheater;
public class DvdPlayer {
String description;
int currentTrack;
Amplifier amplifier;
String movie;
public DvdPlayer(String description, Amplifier amplifier) {
this.description = description;
this.amplifier = amplifier;
}
public void on() {
System.out.println(description + " on");
}
public void off() {
System.out.println(description + " off");
}
public void eject() {
movie = null;
System.out.println(description + " eject");
}
public void play(String movie) {
this.movie = movie;
currentTrack = 0;
System.out.println(description + " playing \"" + movie + "\"");
}
public void play(int track) {
if (movie == null) {
System.out.println(description + " can't play track " + track + " no dvd inserted");
} else {
currentTrack = track;
System.out.println(description + " playing track " + currentTrack + " of \"" + movie + "\"");
}
}
public void stop() {
currentTrack = 0;
System.out.println(description + " stopped \"" + movie + "\"");
}
public void pause() {
System.out.println(description + " paused \"" + movie + "\"");
}
public void setTwoChannelAudio() {
System.out.println(description + " set two channel audio");
}
public void setSurroundAudio() {
System.out.println(description + " set surround audio");
}
public String toString() {
return description;
}
}
package hometheater;
public class PopcornPopper {
String description;
public PopcornPopper(String description) {
this.description = description;
}
public void on() {
System.out.println(description + " on");
}
public void off() {
System.out.println(description + " off");
}
public void pop() {
System.out.println(description + " popping popcorn!");
}
public String toString() {
return description;
}
}
package hometheater;
public class Projector {
String description;
DvdPlayer dvdPlayer;
public Projector(String description, DvdPlayer dvdPlayer) {
this.description = description;
this.dvdPlayer = dvdPlayer;
}
public void on() {
System.out.println(description + " on");
}
public void off() {
System.out.println(description + " off");
}
public void wideScreenMode() {
System.out.println(description + " in widescreen mode (16x9 aspect ratio)");
}
public void tvMode() {
System.out.println(description + " in tv mode (4x3 aspect ratio)");
}
public String toString() {
return description;
}
}
package hometheater;
public class Screen {
String description;
public Screen(String description) {
this.description = description;
}
public void up() {
System.out.println(description + " going up");
}
public void down() {
System.out.println(description + " going down");
}
public String toString() {
return description;
}
}
package hometheater;
public class TheaterLights {
String description;
public TheaterLights(String description) {
this.description = description;
}
public void on() {
System.out.println(description + " on");
}
public void off() {
System.out.println(description + " off");
}
public void dim(int level) {
System.out.println(description + " dimming to " + level + "%");
}
public String toString() {
return description;
}
}
package hometheater;
public class Tuner {
String description;
Amplifier amplifier;
double frequency;
public Tuner(String description, Amplifier amplifier) {
this.description = description;
}
public void on() {
System.out.println(description + " on");
}
public void off() {
System.out.println(description + " off");
}
public void setFrequency(double frequency) {
System.out.println(description + " setting frequency to " + frequency);
this.frequency = frequency;
}
public void setAm() {
System.out.println(description + " setting AM mode");
}
public void setFm() {
System.out.println(description + " setting FM mode");
}
public String toString() {
return description;
}
}
可以观赏电影啦
package hometheater;
public class HomeTheaterTestDrive {
public static void main(String[] args) {
Amplifier amp = new Amplifier("Top-O-Line Amplifier");
Tuner tuner = new Tuner("Top-O-Line AM/FM Tuner", amp);
DvdPlayer dvd = new DvdPlayer("Top-O-Line DVD Player", amp);
CdPlayer cd = new CdPlayer("Top-O-Line CD Player", amp);
Projector projector = new Projector("Top-O-Line Projector", dvd);
TheaterLights lights = new TheaterLights("Theater Ceiling Lights");
Screen screen = new Screen("Theater Screen");
PopcornPopper popper = new PopcornPopper("Popcorn Popper");
HomeTheaterFacade homeTheater = new HomeTheaterFacade(amp, tuner, dvd, cd, projector, lights, screen, popper);
homeTheater.watchMovie("Raiders of the Lost Ark");
homeTheater.endMovie();
}
}
测试效果: Get ready to watch a movie...
Popcorn Popper on
Popcorn Popper popping popcorn!
Theater Ceiling Lights dimming to 10%
Theater Screen going down
Top-O-Line Projector on
Top-O-Line Projector in widescreen mode (16x9 aspect ratio)
Top-O-Line Amplifier on
Top-O-Line Amplifier setting DVD player to Top-O-Line DVD Player
Top-O-Line Amplifier surround sound on (5 speakers, 1 subwoofer)
Top-O-Line Amplifier setting volume to 5
Top-O-Line DVD Player on
Top-O-Line DVD Player playing "Raiders of the Lost Ark"
Shutting movie theater down...
Popcorn Popper off
Theater Ceiling Lights on
Theater Screen going up
Top-O-Line Projector off
Top-O-Line Amplifier off
Top-O-Line DVD Player stopped "Raiders of the Lost Ark"
Top-O-Line DVD Player eject
Top-O-Line DVD Player off
好,关于适配器模式和外观模式就记录到这里,接下来会继续学习新的设计模式:模板方法模式。