深入浅出设计模式-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();
}