前言
外观模式是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,隐藏了系统复杂性,为系统中的一组接口提供了一个统一的访问接口。具有高内聚、低耦合的特点。
外观模式的实现
下面我们以电影的观看步骤为例,假设客户需要观看电影,他不需要了解电影中广告,灯光,音乐,影像的流程,只需要通过一个方法的调用就能实现自己想要观看的影片。
广告类:
public class Advertisement {
public void playAdvertisement() {
System.out.println("playAdvertisement");
}
public void endAdvertisement() {
System.out.println("playAdvertisement");
}
}
电影类:
public class Movie {
String movieName;
public Movie(String movieName) {
super();
this.movieName = movieName;
}
public void play() {
System.out.println("start play "+movieName);
}
public void movieEnd() {
System.out.println(movieName+" end");
}
}
灯光类:
public class Light {
public void lightOn() {
System.out.println("lightOn");
}
public void lightOff() {
System.out.println("lightOff");
}
}
音乐类:
public class Music {
public void startMusic() {
System.out.println("start music");
}
public void stopMusic() {
System.out.println("stop music");
}
}
最后是提供给客户播放电影的访问类:
public class WatchMovieFaced {
private String movieName;
private Movie movie;
private Advertisement advertisement;
private Light light;
private Music music;
public WatchMovieFaced(String movieName) {
super();
this.movieName = movieName;
movie = new Movie(movieName);
advertisement = new Advertisement();
light = new Light();
music = new Music();
}
public void playMovie() {
light.lightOn();
advertisement.playAdvertisement();
advertisement.endAdvertisement();
light.lightOff();
music.startMusic();
movie.play();
movie.movieEnd();
music.stopMusic();
light.lightOn();
}
}
调用案例以及结果:
public class FacedTestDrive {
public static void main(String[] args) {
WatchMovieFaced movieFaced = new WatchMovieFaced("The Shawshank Redemption");
movieFaced.playMovie();
}
}
由以上流程可以看到,客户只需要操作WatchMovieFaced里面的playMovie方法就可以完成需求,无需知道内部复杂的操作步骤。这就是外观模式。
优点:
- 屏蔽了子系统组件,减少了客户端所需处理的对象数目。通过引入外观模式,客户端代码将变得很简单。
- 降低了子系统与客户端之间的耦合度。
- 一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
缺点:
- 并不能限制客户端直接调用子系统,如果客户端对子系统类做太多限制则减少了可变形和灵活性。
- 如果设计不当,增加新的子系统就可能修改外观类的源代码,不符合开闭原则。
网友评论