java 开发模式之八 : 外观模式(门面模式)

原理或定義

它隐藏系统的复杂性,并向客户端提供一个可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性,为子系统中的一组接口提供了一个统一的高层访问接口,这个接口使得子系统更容易被访问或使用。这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。

结构

门面角色( facade ):这是门面模式的核心。它被客户角色调用,因此它熟悉子系统的功能。它内部根据客户角色已有的需求预定了几种功能组合;
子系统角色(subsystem实现了子系统的功能。对它而言, façade角色就和客户角色一样是未知的,它没有任何 façade角色的信息和链接;
客户角色调用 façade角色来完成要得到的功能;

類圖


案例与代码

本模式以智能家电控制项目为示例

使用遥控器通过中央控制器控制DVD和音响



设备类:

public class DVDPlayer {
	private static DVDPlayer instance = null;

	private DVDPlayer() {

	}

	public static DVDPlayer getInstance() {
		if (instance == null) {
			instance = new DVDPlayer();
		}

		return instance;
	}
	
	public void on() {
		System.out.println("DVDPlayer On");
	}

	public void off() {
		System.out.println("DVDPlayer Off");
	}

	public void play() {
		System.out.println("DVDPlayer is playing");
	}
	
	public void pause() {
		System.out.println("DVDPlayer  pause");
	}
	
	public void setdvd() {
		System.out.println("DVDPlayer  is setting dvd");
	}
}
public class Stereo {


	private static Stereo instance = null;
	private int volume = 5;


	private Stereo() {


	}


	public static Stereo getInstance() {
		if (instance == null) {
			instance = new Stereo();
		}


		return instance;
	}


	public void on() {
		System.out.println("Stereo On");
	}


	public void off() {
		System.out.println("Stereo Off");
	}


	public void setVolume(int vol) {


		volume = vol;
		System.out.println("the volume of Stereo is set to  " + volume);
	}


	public void addVolume() {
		if (volume < 11) {
			volume++;
			setVolume(volume);
		}


	}


	public void subVolume() {
		if (volume > 0) {
			volume--;
			setVolume(volume);
		}


	}


}


中央控制器类/外观类:

public class TheaterFacade {
	private Stereo mStereo;
	private DVDPlayer mDVDPlayer;

	public TheaterFacade() {
		mStereo = Stereo.getInstance();
		mDVDPlayer = DVDPlayer.getInstance();
	}

	public void dvd_on(){
		mDVDPlayer.on();
	}

	public void setdvd(){
		mDVDPlayer.setdvd();
	}

	public void dvd_off(){
		mDVDPlayer.off();
	}

	public void play() {
		mDVDPlayer.play();
	}

	public void pause() {
		mDVDPlayer.pause();
	}

	public void stereo_off(){
		mStereo.on();
	}

	public void stereo_on(){
		mStereo.off();
	}

	public void addVolume() {
		mStereo.addVolume();
	}

	public void subVolume() {
		mStereo.subVolume();
	}
}

Client / 遥控器类:

public class Control {
	private TheaterFacade facade;

	public Control() {
		facade = new TheaterFacade();
	}

	public void button1(){
		facade.dvd_on();
	}

	public void button2(){
		facade.setdvd();
	}

	public void button3(){
		facade.dvd_off();
	}

	public void button4() {
		facade.play();
	}

	public void button5() {
		facade.pause();
	}

	public void button6(){
		facade.stereo_off();
	}

	public void button7(){
		facade.stereo_on();
	}

	public void button8() {
		facade.addVolume();
	}

	public void button9() {
		facade.subVolume();
	}
}

提供一个统一的接口,来访问子系统中一群功能相关接口

最少知识原则:尽量减少对象之间的交互,只留几个“密友”

对象的方法调用范围:
该对象本身
作为参数传进来的对象
此方法创建和实例化的对象
对象的组件


使用場景

1. 为一个复杂子系统提供一个简单接口。

2.提高子系统的独立性。

3.在层次化结构中,可以使用Facade模式定义系统中每一层的入口

 

優缺點

主要优点有:

1.对客户程序隐藏子系统细节,因而减少了客户对于子系统的耦合,能够拥抱变化;

2.外观类对子系统的接口封装,使得系统更易于使用;

3.更好的划分访问层次。把需要暴露给外部的功能集中到外观类中,这样既方便客户端使用,也很好地隐藏了内部的细节。

 

缺点主要有

1.外观类接口膨胀,由于子系统的接口都由外观类统一对外暴露,使得外观类的 API 接口较多,在一定程度上增加了用户使用成本;

2.外观类没有遵循开闭原则,当业务出现变更时,可能需要直接修改外观类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值