23种设计模式之一————外观模式详细介绍与讲解

外观模式详细讲解

一、概念

外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用来访问系统中的一群接口,从而简化客户端与系统之间的交互。外观模式通过引入一个外观类来封装子系统的复杂性,使得客户端只需要与外观类交互,而无需直接与子系统的各个组件打交道。

二、 外观模式结构

核心思想及解释

外观模式的核心思想是简化复杂系统的接口。它提供一个统一的接口,客户端通过这个接口与复杂子系统进行交互,而不需要了解子系统的详细工作原理。这种模式允许用户避免直接处理复杂的子系统组件,可以更加简单地对子系统进行访问和管理。

模式的UML类图

模式角色

外观角色(Facade) :这是外观模式的核心角色 ,它提供了一个简化的接口,用于访问子系统中的功能。外观类的作用是封装复杂的子系统操作,让外部客户端无需了解内部细节就能进行交互。
子系统角色(Subsystem) :这些是实际执行具体任务的类或模块。它们可能包含多个类和更复杂的逻辑,对于客户端来说,直接与这些子系统交互可能会非常复杂。
客户角色(Client):客户端使用外观类提供的接口与子系统进行交互。通过这种方式,客户端可以简化其代码,因为它只需要与外观类打交道,而不是直接与复杂的子系统打交道。

应用场景

1.系统复杂度较高 :当系统的某一子系统变得过于复杂,不容易使用时,可以使用外观模式进行简化。它可以将系统的复杂性内部化,对外提供一个简单的接口,使得使用者更加容易使用。
2.系统中存在多个包含关系复杂的接口 :当系统中存在多个接口之间的依赖关系比较复杂时,外观模式可以进行封装,将复杂性内部化,从而简化其使用和维护。
3.需要对外封闭系统 :当系统需要对外封闭,外界只能通过一个统一的接口来访问系统时,可以使用外观模式进行封装,这样可以有效提高系统的安全性。
4.系统需要进行重构 :当系统需要进行重构,需要对原有的代码进行优化和改进时,可以使用外观模式进行重构,使得代码更加易于理解和维护。同时,使用外观模式可以将系统功能进行重组,减少耦合,从而提高系统的灵活性和可扩展性。
5.简化系统接口 :客户端需要使用一个简单易用的接口来操作整个系统,而不需要关心系统的内部实现。
6.封装复杂逻辑 :系统内部的实现非常复杂,需要通过外观模式来将其封装起来,从而便于管理和维护。
7.解耦系统组件:系统内部的各个组件之间存在较高的耦合度,需要通过外观模式来降低其耦合度,从而提高系统的可扩展性和灵活性。

模式优点

  • 简化接口:客户端只需与外观类交互,无需了解系统的复杂性。
  • 解耦客户端和子系统:外观类作为中介者,降低了客户端和子系统之间的耦合度。
  • 提高灵活性:可以随时修改外观类以适应系统变化,而不会影响客户端代码。

模式缺点

  • 不符合"开闭原则":如果新增子系统或删除子系统,可能需要修改外观角色的代码,这在一定程度上违反了"开闭原则"。
  • 可能隐藏了子系统的复杂性:如果外观角色设计得过于复杂,可能会隐藏子系统的复杂性,使得客户端难以理解和使用。
  • 封装过度导致灵活性降低:如果外观类封装了过多的子系统功能,可能会导致其变得过于庞大和复杂,反而增加了理解和维护的难度。当需要修改系统内部实现时,可能需要修改外观类,这可能会影响到其他与外观类交互的客户端。

三、实例演示

图示

代码展示

java 复制代码
package task1;

public class GuaHao {
	private String keshi;

	public GuaHao(String keshi) {
		this.keshi = keshi;
	}

	public boolean IsTrue() {
		if (keshi != null) {
			return true;
		} else
			return false;
	}

}
package task1;

public class Menzhen {
	private GuaHao guaHao;

	public Menzhen(GuaHao guaHao) {
		this.guaHao = guaHao;
	}

	public String check() {
		String str = "健胃消食片";
		if (guaHao.IsTrue()) {//判断是否挂号
			return str;
		} else
			return null;

	}

}
package task1;

public class Huajia {
	private Menzhen menzhen;

	public Huajia(Menzhen menzhen) {
		this.menzhen = menzhen;
	}

	public double Getprice() {
		if (menzhen.check() != null) {
			System.out.println("开的药是:"+menzhen.check());
			return 20;
		} else
			return 0;
	}
}
package task1;

public class Pay {
	private Huajia price;

	public Pay(Huajia price) {
		this.price = price;
	}

	public boolean IsPay() {
		System.out.println("已缴费" + price.Getprice());
		return true;
	}
}
package task1;

public class Medicine {
	public Pay isPay;

	public Medicine(Pay isPay) {
		this.isPay = isPay;
	}

	public void GetMedicine() {
		if (isPay.IsPay()) {
			System.out.println("已取药");
		}
	}

}

然后,我们创建一个外观类,它将子系统的功能进行封装:

java 复制代码
package task1;

public class Facade {
	private GuaHao guaHao;
	private Menzhen menzhen;
	private Huajia huajia;
	private Pay pay;
	private Medicine medicine;
	private String keshi;

	public Facade(String keshi) {
		this.keshi = keshi;
		guaHao = new GuaHao(keshi);
		menzhen = new Menzhen(guaHao);
		huajia = new Huajia(menzhen);
		pay = new Pay(huajia);
		medicine = new Medicine(pay);

	}

	public void check() {
		System.out.println("挂号:"+keshi);
		medicine.GetMedicine();
		

	}

}

最后,我们可以在客户端代码中使用外观类:

java 复制代码
package task1;

public class Test {
	public static void main(String[] args){
		Facade facade = new Facade("内科");
		facade.check();
	}

}

运行结果

在这个示例中,GuaHaoMenzhenHuajiaPayMedicine代表子系统中的不同组件,它们各自负责挂号、门诊、划价、付费和取药。Facade作为外观类,提供了一个check()方法,该方法调用了所有必要的子系统操作来检查,从而简化了客户端 的使用。客户端只需要调用外观类的一个方法,而无需了解每个子系统的具体实现细节。
"博主用心写,读者点关注;互动传真情,知识不迷路

相关推荐
伏颜.9 分钟前
Spring懒加载Bean机制
java·spring
细心的莽夫10 分钟前
集合复习(java)
java·开发语言·笔记·学习·java-ee
yours_Gabriel16 分钟前
java基础:面向对象(二)
java·开发语言·笔记·学习
Enaium19 分钟前
Rust入门实战 编写Minecraft启动器#3解析资源配置
java·开发语言·rust
繁星十年23 分钟前
《C++20设计模式》命令模式思考
设计模式·命令模式·c++20
虫小宝30 分钟前
在Spring Boot中实现多线程任务调度
java·spring boot·spring
虫小宝2 小时前
如何在Java中实现PDF生成
java·开发语言·pdf
菜鸡且互啄692 小时前
在线教育平台,easyexcel使用案例
java·开发语言
八月林城2 小时前
JAVA导出数据库字典到Excel
java·数据库·excel
浅念同学4 小时前
算法-常见数据结构设计
java·数据结构·算法