深入浅出设计模式-008:外观模式(Facade Pattern)
一:将一个或数个类的复杂的一切都隐藏在背后,只显露出一个干净美好的外观 外观没有“封装”子系统的类,外观只是提供简化的接口。所以客户如果觉得有必要,依然可以直接使用子系统类。即提供简化接口的同时,依然将系统完整的功能暴露出来,以供需要的人使用。 外观不仅是简化了接口,也将客户从组件的子系统中解耦。 外观和适配器可以包装许多类,但是外观的意图是简化接口,而适配器的意图是将接口转换成不同的接口。 二:外观模式:提供一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
三:设计原则:最少只是:减少对象之间的交互,只留下几个“密友”。即只和你的密友谈话。 这个原则希望我们在设计中,不要让太多的类耦合在一起,免得修改系统中的一部分,会影响到其他的部分。 如果系统类之间相互依赖,那么这个系统就会变成一个易碎的系统,它需要花许多成本维护,也会因为太复杂而不容易被其他人了解。
四:当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器。 当需要简化并统一一个很大的接口或者一群复杂的接口时,使用外观。 适配器改变接口以符合客户的期望。 外观将客户从一个复杂的子系统中解耦。 实现一个适配器可能需要一番功夫,也可能不费功夫,视目标接口的大小与复杂度而定。 实现一个外观,需要将子系组合进外观中,然后将工作委托给子系统执行。 适配器模式的两种形式:对象适配器和类适配器。类适配器需要用到多重继承。 你可以为一个子系统实现一个以上的外观。 适配器将一个对象包装起来以改变其接口。装饰者将一个对象包装起来以增加新的行为和责任,而外观将一群对象包装起来以简化接口
五:如组合音响,不用一步步的操作来完成,可以封装成一个按钮。 public class Amplifier { Tuner tuner; DvdPlayer dvd; CdPlayer cd; } public class Tuner { } public class DvdPlayer { Amplifier amplifier; } public class CdPlayer { Amplifier amplifier; } public class Projector { DvdPlayer dvdPlayer; } public class TheaterLights {} public class Screen {} public class PopcornPopper {} public class HomeTheaterFacade { Amplifier amp; Tuner tuner; DvdPlayer dvd; CdPlayer cd; Projector projector; TheaterLights lights; Screen screen; PopcornPopper popper; public HomeTheaterFacade(Amplifier amp, Tuner tuner, DvdPlayer dvd, CdPlayer cd, Projector projector, Screen screen, TheaterLights lights, PopcornPopper popper) { this.amp = amp; this.tuner = tuner; this.dvd = dvd; this.cd = cd; this.projector = projector; this.screen = screen; this.lights = lights; this.popper = popper; }
//将看电影前的一序列复杂动作封装成一个简化的接口 public object WatchMovie(string movie) { StringBuilder watchMovieString = new StringBuilder();
watchMovieString.Append("Get ready to watch a movie.../n"); watchMovieString.Append(popper.On());//打开爆米花机 watchMovieString.Append(popper.Pop());//开始爆米花 watchMovieString.Append(lights.Dim(10));//灯光调暗到10% watchMovieString.Append(screen.Down());//把屏幕放下 watchMovieString.Append(projector.On());//打开投影机 watchMovieString.Append(projector.WideScreenMode());//将投影机设置到屏幕模式 watchMovieString.Append(amp.On());//打开功放 watchMovieString.Append(amp.SetDvd(dvd));//是指DVD watchMovieString.Append(amp.SetSurroundSound());//设置成环绕立体模式 watchMovieString.Append(amp.SetVolume(5));//音量调到5 watchMovieString.Append(dvd.On());//打开DVD watchMovieString.Append(dvd.Play(movie));//终于可以看电影了
return watchMovieString.ToString(); } public object EndMovie() { StringBuilder endMovieString = new StringBuilder();
endMovieString.Append("Shutting movie theater down.../n"); endMovieString.Append(popper.Off()); endMovieString.Append(lights.On()); endMovieString.Append(screen.Up()); endMovieString.Append(projector.Off()); endMovieString.Append(amp.Off()); endMovieString.Append(dvd.Stop()); endMovieString.Append(dvd.Eject()); endMovieString.Append(dvd.Off());
return endMovieString.ToString(); }
public object ListenToCd(string cdTitle) { StringBuilder listenToCdString = new StringBuilder();
listenToCdString.Append("Get ready for an audio experence.../n"); listenToCdString.Append(lights.On()); listenToCdString.Append(amp.On()); listenToCdString.Append(amp.SetVolume(5)); listenToCdString.Append(amp.SetCd(cd)); listenToCdString.Append(amp.SetStereoSound()); listenToCdString.Append(cd.On()); listenToCdString.Append(cd.Play(cdTitle));
return listenToCdString.ToString(); }
public object EndCd() { StringBuilder endCdString = new StringBuilder();
endCdString.Append("Shutting down CD.../n"); endCdString.Append(amp.Off()); endCdString.Append(amp.SetCd(cd)); endCdString.Append(cd.Eject()); endCdString.Append(cd.Off());
return endCdString.ToString(); }
public object ListenToRadio(double frequency) { StringBuilder listenToRadioString = new StringBuilder();
listenToRadioString.Append("Tuning in the airwaves.../n"); listenToRadioString.Append(tuner.On()); listenToRadioString.Append(tuner.SetFrequency(frequency)); listenToRadioString.Append(amp.On()); listenToRadioString.Append(amp.SetVolume(5)); listenToRadioString.Append(amp.SetTuner(tuner));
return listenToRadioString.ToString(); }
public object EndRadio() { StringBuilder endRadioString = new StringBuilder();
endRadioString.Append("Shutting down the tuner.../n"); endRadioString.Append(tuner.Off()); endRadioString.Append(amp.Off());
return endRadioString.ToString(); } }
static void Main(string[] args) { Amplifier amp = new Amplifier("Top-O-Line Amplifier"); Tuner tuner = new Tuner("Top-O-Line Tuner", amp); DvdPlayer dvd = new DvdPlayer("Top-O-Line DVD Player", amp); CdPlayer cd = new CdPlayer("Top-O-Line CD Player", amp); Projector 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, screen, lights, popper);
homeTheater.WatchMovie("Toy Story"); homeTheater.EndMovie();
homeTheater.ListenToCd("Dark Side of the Moon"); homeTheater.EndCd();
homeTheater.ListenToRadio(92.5); homeTheater.EndRadio(); }