定义:为子系统中的一组接口提供一个一致的界面,facaede模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
案例:
2 投资者买股片vs基金
投资者买股票,需要了解股票的各种信息,预测它的未来,风险反而大
投资者买基金,基金经理人相对专业,不容易像散户那么盲目,基金经理人拿这些钱去做投资,然后大家获利
由于在众多投资者对众多股票的联系太多,反而不利于操作,耦合性过高。而有了基金以后,变成了众多用户只和基金打交道,实际的操作却是基金经理人在与上千只股票和其他投资产品打交道。
class Stock1
{
public void Sell()
{
System.out.println("股票1卖出");
}
public void Buy()
{
System.out.println("股票1买入");
}
}
class Stock2
{
public void Sell()
{
System.out.println("股票2卖出");
}
public void Buy()
{
System.out.println("股票2买入");
}
}
class Stock3
{
public void Sell()
{
System.out.println("股票3卖出");
}
public void Buy()
{
System.out.println("股票3买入");
}
}
class NationalDebt1
{
public void Sell()
{
System.out.println("国债卖出");
}
public void Buy()
{
System.out.println("国债买入");
}
}
class Realty
{
public void Sell()
{
System.out.println("房地产卖出");
}
public void Buy()
{
System.out.println("房地产买入");
}
}
class Fund
{
Stock1 gu1;
Stock2 gu2;
Stock3 gu3;
NationalDebt1 nd1;
Realty rt1;
public Fund() {
gu1=new Stock1();
gu2=new Stock2();
gu3=new Stock3();
nd1=new NationalDebt1();
rt1=new Realty();
}
public void BuyFund()
{
gu1.Buy();
gu2.Buy();
gu3.Buy();
nd1.Buy();;
rt1.Buy();;
}
public void SellFund()
{
gu1.Sell();
gu2.Sell();
gu3.Sell();
nd1.Sell();
rt1.Sell();
}
}
public class main
{
public static void main(String[] args) {
Fund jijin=new Fund();
jijin.BuyFund();
jijin.SellFund();}
}
此时,用户不需要了解股票,甚至可以对股票一无所知,买过基金过一段时间后再赎回就可以数钱了。参与股票的具体买卖都由基金公司完成。
基金类是系统中一组接口的封装界面,也就是高层接口,通过调用高层接口,可以直接调用一组子接口而不需要了解子接口是如何实现的,具有高度保密性和代码复用性。
class SubSystemOne
{
public void MethodOne()
{
System.out.println("子系统方法一");
}
}
class SubSystemTwo
{
public void MethodTwo()
{
System.out.println("子系统方法二");
}
}
class SubSystemThree
{
public void MethodThree()
{
System.out.println("子系统方法三");
}
}
class SubSystemFour
{
public void MethodFour()
{
System.out.println("子系统方法四");
}
}
class Facade//外观类
{
SubSystemOne one;
SubSystemTwo Two;
SubSystemThree Three;
SubSystemFour Four;
public Facade()
{
one=new SubSystemOne();
Two=new SubSystemTwo();
Three=new SubSystemThree();
Four=new SubSystemFour();
}
public void MethodA()
{
System.out.println("\n方法组A()");
one.MethodOne();
Two.MethodTwo();
Four.MethodFour();
}
public void MethodB()
{
System.out.println("\n方法组B()");
Two.MethodTwo();
Three.MethodThree();
}
}
public class main
{
public static void main(String[] args) {
Facade facade=new Facade();
facade.MethodA();
facade.MethodB();
}
}
保安系统的例子
一个保安系统由两个录像机,三个电灯,一个遥感器和一个警报器组成
保安系统的操作人员需要经常将这些仪器启动和关闭。
外观模式使用的三个阶段:
- 设计初期,应该有意识将不同的两个层分离,这样可以为复杂的子系统提供一个简单的接口使得耦合度大大降低。
- 在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,增加外观Facaed可以提供一个简单的接口,减少它们之间的依赖。
- 在维护一个遗留的大型系统时,可以使用外观模式Facaed:为新系统开发一个外观Facaed类,来提供设计粗糙或高度复杂的遗留代码的比较清晰的简单接口,让新系统与Facaed对象交互。希望包装或隐藏原有系统
外观模式的优点
- 屏蔽了外部客户端和系统内部模板的交互。
- Facaed的功能可以被多个客户端调用,可以实现复用
- 对使用Facaed的人员来说,Facaed大大的节省了他们的学习成本。
本质:
封装交互,简化调用