设计模式完结(10)--外观模式
来个中间类 即 外观类 来关联多个业务类,与多个业务交互, 客户端与外观类交互, 降低客户端和这些类的耦合。
如果业务类有变化,外观类 定义为 抽象类,多个实现。
一个客户类需要和多个业务类交互,而这些需要交互的业务类经常会作为一个整体出现,由于涉及到的类比较多,导致使用时代码较为复杂,此时,特别需要一个类似服务员一样的角色,由它来负责和多个业务类进行交互,而客户类只需与该类交互。引入一个新的外观类(Facade)来实现该功能,外观类充当了软件系统中的“服务员”
外观模式
外观模式是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。
class SubSystemA { public void MethodA() { //业务实现代码 } } class SubSystemB { public void MethodB() { //业务实现代码 } } class SubSystemC { public void MethodC() { //业务实现代码 } } class Facade { private SubSystemA obj1 = new SubSystemA(); private SubSystemB obj2 = new SubSystemB(); private SubSystemC obj3 = new SubSystemC(); public void Method() { obj1.MethodA(); obj2.MethodB(); obj3.MethodC(); } } class Program { static void Main(string[] args) { Facade facade = new Facade(); facade.Method(); } }
EncryptFacade:加密外观类,充当外观类。 namespace FacadeSample { class EncryptFacade { //维持对其他对象的引用 private FileReader reader; private CipherMachine cipher; private FileWriter writer; public EncryptFacade() { reader = new FileReader(); cipher = new CipherMachine(); writer = new FileWriter(); } //调用其他对象的业务方法 public void FileEncrypt(string fileNameSrc, string fileNameDes) { string plainStr = reader.Read(fileNameSrc); string encryptStr = cipher.Encrypt(plainStr); writer.Write(encryptStr, fileNameDes); } } } Program:客户端测试类 class Program { static void Main(string[] args) { EncryptFacade ef = new EncryptFacade(); ef.FileEncrypt("src.txt", "des.txt"); Console.Read(); } }
需要增加、删除或更换与外观类交互的子系统类,所以可以引入抽象外观类。
引入抽象外观类之后,客户端可以针对抽象外观类进行编程,对于新的业务需求,不需要修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象。
******在以下情况下可以考虑使用外观模式:
(1) 当要为访问一系列复杂的子系统提供一个简单入口时可以使用外观模式。
(2) 客户端程序与多个子系统之间存在很大的依赖性。引入外观类可以将子系统与客户端解耦,从而提高子系统的独立性和可移植性。
(3) 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。