设计模式学习--适配器模式(Adapter Pattern)+外观模式(Facade Pattern)

设计模式学习--适配器模式(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


好,关于适配器模式和外观模式就记录到这里,接下来会继续学习新的设计模式:模板方法模式。

你可能感兴趣的:(设计模式学习--适配器模式(Adapter Pattern)+外观模式(Facade Pattern))