什么是外观模式?
问题引入:投资者买股票vs基佥
有些人可能炒过股票,但其实大部分人都不太懂,这种没有足够了解证券知识的情况下做股票是很容易亏钱的,刚开始炒股肯定都会想,如果有个懂行的帮帮手就好,其实基金就是个好帮手,支付宝里就有许多的基金,它将投资者分散的资金集中起来,交由专业的经理人进行管理,投资于股票、债券、外汇等领域,而基金投资的收益归持有者所有,管理机构收取一定比例的托管管理费用。
投资者买股票,需要了解股票的各种信息,预测它的未来买入和卖出的时机合适,这很难做到,风险反而大。投资者买基金,基金经理人相对专业,不容易像散户那么盲目,基金经理人用这些钱去做投资,然后大家获利,
这体现了软件开发当中的什么?由于众多投资者对众多股票的联系太多,反而不利于操作这在软件中称为耦合性过高。而有了基金以后,变成众多用户只和基金打交道,关心基金的上涨和下跌就可以了,实际上的操作却是基金经理人在与上千支股票和其他投资产品打交道。这就是外观模式。
投资基金版本代码结构图
投资基金版本代码
package 外观模式;
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 NationalDebt1{
//卖国债
public void Sell() {
System.out.println("国债1卖出");
}
//买国债
public void Buy() {
System.out.println("国债1买入");
}
}
class Realty1{
//卖房地产
public void Sell() {
System.out.println("房地产1卖出");
}
//买房地产
public void Buy() {
System.out.println("房地产1买入");
}
}
//基金类
class Fund{
Stock1 gu1;
Stock2 gu2;
NationalDebt1 nd1;
Realty1 rt1;
public Fund() {
gu1=new Stock1();
gu2=new Stock2();
nd1=new NationalDebt1();
rt1=new Realty1();
}
public void BuyFund() {
gu1.Buy();
gu2.Buy();
nd1.Buy();
rt1.Buy();
}
public void SellFund() {
gu1.Sell();
gu2.Sell();
nd1.Sell();
rt1.Sell();
}
}
public class Main1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Fund f1=new Fund();
f1.BuyFund();
f1.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("方法A()----");
one.MethodOne();
two.MethodTwo();
four.MethodFour();
}
public void MethodB() {
System.out.println("方法B()----");
two.MethodTwo();
three.MethodThree();
}
}
客户端
public class FacadeMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
Facade facade = new Facade();
facade.MethodA();
facade.MethodB();
}
}
外观模式的应用
1.使用时机
- 客户端不需要知道系统内部的复杂联系,整个系统只提供一个“接待员”即可
- 定义系统的入口
2.方法 - 客户端不与系统耦合,外观类与系统耦合
3.优点 - 减少了系统的相互依赖
- 提高了灵活性。不管系统内部如何变化,只要不影响到外观对象,任你自由活动
- 提高了安全性。想让你访问子系统的哪些业务就开通哪些逻辑,不在外观上开通的方法,你就访问不到
4. 缺点 - 不符合开闭原则,修改很麻烦
5. 使用场景 - 为一个复杂的模块或子系统提供一个外界访问的接口
- 子系统相对独立,外界对子系统的访问只要黑箱操作即可
- 预防低水平人员带来的风险扩散
它完美地体现了依赖倒转原则和迪米特法则的思想,所以是非常常用的模式之一。