设计模式系列|之外观(门面)模式
2023-03-09 22:15:23 时间
本文转载自微信公众号「狼王编程」,作者狼王。转载本文请联系狼王编程公众号。
1、概述
外观模式是一种结构型设计模式, 能为程序库、 框架或其他复杂类提供一个简单的接口。
避免多种不相关的功能污染单一外观, 使其变成又一个复杂结构。客户端和其他外观都可使用附加外观。
2、适用场景
1)如果你需要一个指向复杂子系统的直接接口, 且该接口的功能有限, 则可以使用外观模式。外观将会提供指向子系统中最常用功能的快捷方式, 能够满足客户端的大部分需求。
2)如果需要将子系统组织为多层结构, 可以使用外观。你可以为每个层次创建一个外观, 然后要求各层的类必须通过这些外观进行交互。
3、实例
有以下场景:
当前有学生子系统,该系统有三个接口,查询学生姓名,查询学生年龄,查询学生家庭地址。
有一个教学系统,要分别去调用这三个接口。
有一个成绩系统,要分别调用者三个接口。
有一个考试系统,也要分别调用这三个系统。
3.1 不使用外观模式时候
- /**
- * 学生
- */
- public class Student {
- private String name = "狼王";
- private int age = 25;
- private String address = "上海";
- public Student(String name, int age, String address) {
- this.name = name;
- this.age = age;
- this.address = address;
- }
- public Student(){
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- }
- /**
- * 学生
- */
- public class Student {
- private String name = "狼王";
- private int age = 25;
- private String address = "上海";
- public Student(String name, int age, String address) {
- this.name = name;
- this.age = age;
- this.address = address;
- }
- public Student(){
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- }
- /**
- * 年龄接口
- */
- @Service
- public class StudentAgeService implements IStudentAge{
- @Override
- public int getAge() {
- Student student = new Student();
- return student.getAge();
- }
- }
- @Service
- public class StudentNameService implements IStudentName{
- @Override
- public String getName() {
- Student student = new Student();
- return student.getName();
- }
- }
三个外部服务
- /**
- * 教育服务
- */
- @Service
- public class EduService {
- @Autowired
- private StudentNameService studentNameService;
- @Autowired
- private StudentAgeService studentAgeService;
- @Autowired
- private StudentAddressService studentAddressService;
- public void getStudentName(){
- System.out.println("学生姓名是:" + studentNameService.getName());
- }
- public void getStudentAge(){
- System.out.println("学生年龄是:" + studentAgeService.getAge());
- }
- public void getStudentAddress(){
- System.out.println("学生地址是:" + studentAddressService.getAddress());
- }
- }
- /**
- * 考试服务
- */
- @Service
- public class ExamService {
- @Autowired
- private StudentNameService studentNameService;
- @Autowired
- private StudentAgeService studentAgeService;
- @Autowired
- private StudentAddressService studentAddressService;
- public void getStudentName(){
- System.out.println("学生姓名是:" + studentNameService.getName());
- }
- public void getStudentAge(){
- System.out.println("学生年龄是:" + studentAgeService.getAge());
- }
- public void getStudentAddress(){
- System.out.println("学生地址是:" + studentAddressService.getAddress());
- }
- }
- /**
- * 成绩服务
- */
- @Service
- public class ScoreService {
- @Autowired
- private StudentNameService studentNameService;
- @Autowired
- private StudentAgeService studentAgeService;
- @Autowired
- private StudentAddressService studentAddressService;
- public void getStudentName(){
- System.out.println("学生姓名是:" + studentNameService.getName());
- }
- public void getStudentAge(){
- System.out.println("学生年龄是:" + studentAgeService.getAge());
- }
- public void getStudentAddress(){
- System.out.println("学生地址是:" + studentAddressService.getAddress());
- }
- }
3.2 使用外观模式
在学生服务这里增加一个外观service
- /**
- * 外观模式服务
- */
- @Service
- public class StudentFacedService {
- @Autowired
- private StudentNameService studentNameService;
- @Autowired
- private StudentAgeService studentAgeService;
- @Autowired
- private StudentAddressService studentAddressService;
- public String getStudentName(){
- return studentNameService.getName();
- }
- public int getStudentAge(){
- return studentAgeService.getAge();
- }
- public String getStudentAddress(){
- return studentAddressService.getAddress();
- }
- }
三个调用服务只需要引入外观服务
- /**
- * 教育服务
- */
- @Service
- public class EduService {
- @Autowired
- private StudentFacedService studentFacedService;
- public void getStudentName() {
- System.out.println("学生姓名是:" + studentFacedService.getStudentName());
- }
- public void getStudentAge() {
- System.out.println("学生年龄是:" + studentFacedService.getStudentAge());
- }
- public void getStudentAddress() {
- System.out.println("学生地址是:" + studentFacedService.getStudentAddress());
- }
- }
- /**
- * 考试服务
- */
- @Service
- public class ExamService {
- @Autowired
- private StudentFacedService studentFacedService;
- public void getStudentName() {
- System.out.println("学生姓名是:" + studentFacedService.getStudentName());
- }
- public void getStudentAge() {
- System.out.println("学生年龄是:" + studentFacedService.getStudentAge());
- }
- public void getStudentAddress() {
- System.out.println("学生地址是:" + studentFacedService.getStudentAddress());
- }
- }
- /**
- * 成绩服务
- */
- @Service
- public class ScoreService {
- @Autowired
- private StudentFacedService studentFacedService;
- public void getStudentName() {
- System.out.println("学生姓名是:" + studentFacedService.getStudentName());
- }
- public void getStudentAge() {
- System.out.println("学生年龄是:" + studentFacedService.getStudentAge());
- }
- public void getStudentAddress() {
- System.out.println("学生地址是:" + studentFacedService.getStudentAddress());
- }
- }
4、分析
以上两种方式代码结构如下所示:
从上面两张图可以看到,对于外部服务来说,极大的缩减了代码复杂度,只需要调用学生服务的一个接口。
5、总结
优点:
让客户端代码独立独立于复杂的子系统,且减少对于子系统的依赖。
缺点:
过于庞大的外观,会使得该外观称成为上帝对象,造成所有类的耦合,可通过它操作所有的类功能。
好了。今天就说到这了,我还会不断分享自己的所学所想,希望我们一起走在成功的道路上!
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的