【设计模式十一之门面模式】门面模式(外观模式)详解

细说门面模式

提示:
博主:章飞 _906285288的博客
博客地址:http://blog.csdn.net/qq_29924041


细说门面模式

在说门面模式之前,先浅显的讲一下啥叫门,门是指建筑物的出入口或安装在出入口能开关的装置。想一想你家的大门是不是进入内部的唯一通道啊,那还有后门也可以进入啊。把门的概念引入到程序中,其实也就是统一的入口,进去之后,你有可以进厨房,进卧室,进客厅,以及你想进的房间内等等。

定义

门面模式:外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。门面模式又称为外观模式,它是一种对象结构型模式。
其实也就是通过一个统一的入口,来对子系统的行为进行访问的过程

UML

在这里插入图片描述
来自百度百科的UML图示,可以看到,外部client如果想要去访问子系统的话,这个时候,必须要通过Facade才能进行访问。

门面(Facade)角色 :客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。

子系统(SubSystem)角色 :可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合。每个子系统都可以被客户端直接调用或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。外观模式中所指的子系统是一个广义的概念,它可以是一个类、一个功能模块、系统的一个组成部分或者一个完整的系统。子系统类通常是一些业务类,实现了一些具体的、独立的业务功能

它为子系统中的一组接口提供一个统一的高层接口。这一接口使得子系统更加容易使用。

门面模式场景

场景一

来自设计模式之禅中的案例,举得是寄信的例子,一个用户如果想要寄信,必须要先写信,写地址,将信插入到信封中,然后再把信寄出去,如果邮局现在提供一个服务,有专门人负责接待用户,用户只需要将内容和地址提供出来之后,由邮局服务人员直接进行操作后,将信寄出。可以想想,如果由用户自己去进行操作的话,那么此时需要经历4个步骤,而如果给服务人员的话,此时只要一步,即提供信息,而如果在整个系统中检测机制的话,此时也是直接交给了邮递服务人员。
在例子中,邮费服务人员其实也就是邮局的门面,主要负责整个邮递过程中其它子系统的接洽等等,用户其实也就是Client对象

场景二

此案例举的是医院的案例,一个病人去医院看病,首先需要挂号,然后排队,就诊,拿药等等需要经历这一系列的顺序,如果把医院看做一个系统的话,那么医院里面的每个科室其实都是一个子系统。但是如果这个时候引入一个接待员,病人只要和接待员进行接触就行了,剩下的所有步骤都可以让接待员去操作。因此也引入这个图
在这里插入图片描述
所有的病人其实只要和接待员进行接触就可以了。

场景三

其实你在公司也就有一个很典型的案例,想想是不是有句话叫做,前台就是公司的门面,是的啊,在很多时候,员工的需求很多时候都是提供给了前台行政人员。再由行政人员去协调公司的一些资源,在这个案例中,外访或者员工其实就是Client,而前台行政人员对应Facade,公司的所有部门组成了一个完整的系统,每个部门其实都是一个子系统

上代码

代码一:

定义一个寄信接口

package src.com.zzf.designpattern.facadepattern.demo1;


public interface ILetterProcess {
	//写信
	public void writeContext(String context);
	//填写地址
	public void fillEnvelop(String address);
	//将信填入到信封中
	public void letterIntoEnvelop();
	//寄送信件
	public void sendLetter();
	
	public void sendLetter2(String context,String address);
}

写信的具体步骤信息

package src.com.zzf.designpattern.facadepattern.demo1;


public class LetterProcessImpl implements ILetterProcess{

	public void writeContext(String context) {
		// TODO Auto-generated method stub
		System.out.println("writeContext:"+context);
	}

	public void fillEnvelop(String address) {
		// TODO Auto-generated method stub
		System.out.println("fillEnvelop:"+address);
	}

	public void letterIntoEnvelop() {
		// TODO Auto-generated method stub
		System.out.println("letterIntoEnvelop");
	}

	public void sendLetter() {
		// TODO Auto-generated method stub
		System.out.println("sendLetter");
	}

	
	public void sendLetter2(String context, String address) {
		// TODO Auto-generated method stub
		writeContext(context);
		fillEnvelop(address);
		letterIntoEnvelop();
		sendLetter();
	}

}

邮政人员,也就是邮局的门面,可以负责对寄件人收到的信息进行处理,并寄送

package src.com.zzf.designpattern.facadepattern.demo1;

public class ModenPostOffice {
	ILetterProcess mImpl = new LetterProcessImpl();
	Police mPolice = new Police();
	public void sendLetter(String context,String address){
		if (mImpl != null) {
			mImpl.writeContext(context);
			mImpl.fillEnvelop(address);
			mPolice.checkEnvelop(mImpl);
			mImpl.letterIntoEnvelop();
			mImpl.sendLetter();
		}
	}
}

定义邮政警察,便于在寄送过程中去查验,作为子系统的一个组成部分

package src.com.zzf.designpattern.facadepattern.demo1;


public class Police {
	public void checkEnvelop(ILetterProcess mILetterProcess){
		System.out.println("checkEnvelop:"+mILetterProcess.toString());
	}
}

package src.com.zzf.designpattern.facadepattern.demo1;


/**
 * 
 * @author Administrator
 *门面模式(Facade Pattern):
 *外部与一个子系统的通信必须通过一个统一的外观对象进行,
 *为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
 *门面模式又称为外观模式,它是一种对象结构型模式
 */

public class FacadePatternTest {
	public static void main(String[] args) {
		ILetterProcess mImpl  = new LetterProcessImpl();
		mImpl.writeContext("һhello");
		mImpl.fillEnvelop("address");
		mImpl.letterIntoEnvelop();
		mImpl.sendLetter();
		
		mImpl.sendLetter2("һhello222", "address222");
		
		
		ModenPostOffice modenPostOffice = new ModenPostOffice();
		modenPostOffice.sendLetter("Happy Road No. 666,God Province,Heaven", "Hello,It's me,do you know who I am? I'm your old lover.'d like to....");
	}
}

代码二

定义挂号部门

package src.com.zzf.designpattern.facadepattern.demo2;

public class RegistrationDept {
	public void registrate() {
		System.out.println("挂号");
	}
}

门诊部门

package src.com.zzf.designpattern.facadepattern.demo2;

public class OutpatientDept {
	
	public void outpatient() {
		// TODO Auto-generated method stub
		System.out.println("门诊");
	}
	
}

药房

package src.com.zzf.designpattern.facadepattern.demo2;

public class MedicineDept {
	public void withDrawMedicine() {
		System.out.println("取药");
	}
}

化验部门

package src.com.zzf.designpattern.facadepattern.demo2;

public class AssayDept {
	public void assay() {
		// TODO Auto-generated method stub
		System.out.println("化验");
	}
}

接待员

package src.com.zzf.designpattern.facadepattern.demo2;

public class HospitalFacade {
	AssayDept assayDept = new AssayDept();
	MedicineDept medicineDept = new MedicineDept();
	OutpatientDept outpatientDept =new OutpatientDept();
	RegistrationDept registrationDept = new RegistrationDept();
	
	public void service() {
		registrationDept.registrate();
		outpatientDept.outpatient();
		assayDept.assay();
		medicineDept.withDrawMedicine();
	}
}

病人类

package src.com.zzf.designpattern.facadepattern.demo2;

public class PatientClient {
	public static void main(String[] args) {
		HospitalFacade hospitalFacade = new HospitalFacade();
		hospitalFacade.service();
	}
}

可以看到其实门面模式是通过一个门面来对某一个系统下的所有子系统进行访问的这样的一种模式

优缺点

优点

1 为一个复杂子系统提供一个简单接口
2 提高子系统的独立性
3 在层次化结构中,可以使用Facade模式定义系统中每一层的入口。
4 适合

缺点

缺点:不符合开闭原则。所谓的开闭原则是软件工程里面一个最基本的原则:对扩展开放,对修改关闭。换句话说,你的系统可以提供新的功能模块而不必进行修改




欢迎继续访问,我的博客
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值