设计模式—外观模式
前言
软件开发过程中,客户端经常与复杂的系统内部的子系统进行耦合,从而导致客户单程序随着子系统的变化而变化,为了将他们解耦而产生是外观模式,也称作门面模式
外观模式介绍
外观模式提供了统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用。即创建一个统一的类用来保证子系统中一个或多个负责的类型,客户端直接通过外观模式来调用子系统的方法,从而减少了客户端和子系统的耦合
1)实际例子
学生选择课程并且通知功能
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { /// <summary> /// 以学生选课系统为例子演示外观模式的使用 /// 学生选课模块包括功能有: /// 验证选课的人数是否已满 /// 通知用户课程选择成功与否 /// 外观类 public class RegistrationFacade { private RegisterCourse _registerCourse; private NotifyStudent _notifyStudent; public RegistrationFacade() { _registerCourse = new RegisterCourse(); _notifyStudent = new NotifyStudent(); } public bool RegisterCourse(string courseName, string studentName) { if (!_registerCourse.CheckAvaliable(courseName)) { return false; } return _notifyStudent.Notify(studentName); } } public class RegisterCourse { public bool CheckAvaliable(string courseName) { Console.WriteLine("正在验证课程{0}是否人数已满", courseName); return true; } } public class NotifyStudent { public bool Notify(string studentName) { Console.WriteLine("正在向学生{0}发送通知", studentName); return true; } } }
客户端调用不使用外观模式:
void test() { RegisterCourse registerCourse = new RegisterCourse(); NotifyStudent notifyStudent = new NotifyStudent(); var courseName = "C#"; var studentName = "明明"; if (!registerCourse.CheckAvaliable(courseName)) { Console.WriteLine("选课失败"); } if (notifyStudent.Notify(studentName)) Console.WriteLine("选课成功"); else Console.WriteLine("选课失败"); }
使用外观模式:
static void Main(string[] args) { RegistrationFacade facade = new RegistrationFacade(); if (facade.RegisterCourse("C#", "明明")) Console.WriteLine("选课成功"); else Console.WriteLine("选课失败"); }
2)外观模式介绍
使用外观模式降低了客户单和子系统的耦合度。外观模式核心是:有外观类去保存各个子系统的引用,实现由一个统一的外观类去包装多个子系统,而客户单只需要引用这个外观类,然后有外观类来调用各个子系统。
这样的模式类型与适配器模式,但是有不同:适配器是将一个对象包装起来以改变其接口,而外观模式是将一群对象包装起来以简化其接口,意图不一样。
外观类角色:客户端调用这个角色方法,该角色知道相关的一个或多个子系统的功能和自然,从客户端发出的请求委派到相应的子系统中
3)外观模式分析
优点:外观模式屏蔽了子系统组件,从而简化了接口,减少客户端处理的对象数据并使子系统的使用更加简单
外观模式实现了客户单和子系统的耦合关键,而子系统内部的功能是紧耦合的,松耦合是子系统的变化不会影响到客户端
缺点:如果修改了子系统那么需要修改外观类或客户端的源码
4)使用场景
为一个复杂的子系统提供简单的接口
提供子系统的独立性
在层次结构中,可以定义外观模式定义系统中每一层的入口