设计模式——外观模式

本文主要是讲述结构型模式中一个比较常用的模式-外观模式,这个模式呢,有个最大的特点将细粒度的对象包装成粗粒度的对象,应用程序通过

访问这个外观对象,来完成细粒度对象的调用,外观模式一般是分布式应用和系统架构中的应用服务层的设计中常用的方式,并且一般结合外观模式+DTO

来完成服务层的设计,提供分布式应用服务的高效服务,外观模式我们可以这样理解,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具

体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性。本文将会从以下几个方面进行讲述:

       1、外观模式的使用场景和特点

       2、外观模式的实现方案。

       3、总结外观模式。

我们这里先给出一个外观模式的原理图:

设计模式——外观模式

这是未使用外观模式之前的情况,下面给出使用外观模式后的情形:

设计模式——外观模式

通过外观对象来组织细粒度的服务的调用,外观对象提供给外部应用程序可

以使用的服务,而具体的调用细粒度的过程则被外观对象给封装起来,当然这个过程就是封装变化的部分,而将变化的部分与应用程序进行隔离,无疑对程

序的易用性和可维护性都是很大的提高。

外观模式的特点及使用场景

外观模式的主要思想是将复杂的细粒度的对象服务包装成简单的易使用的粗粒度的功能服务,我们大家最容易理解和知道的外观模式就是,使用的API

接口的封装,我们将第三方的API接口引入到我们的项目中的时候,我们需要对这些接口进行包装,将细粒度的具体调用过程进行包装成外观类的形式,通

过外观类来进行统一的调用。我们平时把一些常用的公共方法也可以简易的称之为外观模式,我们将复杂的细粒度的功能,包装成一个比较通用的简易的的

粗粒度的功能。我们来看看哪些场景下,我们使用外观模式很适合呢?

      1、我们在使用第三方类库或者API的时候,我们通过本地的API接口的封装,来完成对第三方API接口的粗粒度外观对象,通过这个外观对象可以很容

易的完成服务的调用。我们这里举例说明吧,例如现在我有一个发送手机短信的API接口,是第三方提供给我的API接口,那么我如何包装呢?

下面给出对API封装的相关代码和说明

    public class MessageHelper 
    { 
        private static readonly MessageHelper instance = new MessageHelper();

        #region API接口

        [DllImport("EUCPComm.dll", EntryPoint = "SendSMS")]  //即时发送 
        private static extern int SendSMS(string sn, string mn, string ct, string priority);

        [DllImport("EUCPComm.dll", EntryPoint = "SendSMSEx")]  //即时发送(扩展) 
        private static extern int SendSMSEx(string sn, string mn, string ct, string addi, string priority);

        [DllImport("EUCPComm.dll", EntryPoint = "SendScheSMS")]  // 定时发送 
        private static extern int SendScheSMS(string sn, string mn, string ct, string ti, string priority);

        #endregion

        #region 对上面的API包装后的方法

        public int SendSMSEx1(string sn, string mn, string ct, string addi, string priority) 
        { 
            return SendSMSEx(sn, mn, ct, addi, priority); 
        }

        public int SendSMS1(string sn, string mn, string ct, string priority) 
        { 
            return SendSMS(sn, mn, ct, priority); 
        }

        public int SendScheSMS1(string sn, string mn, string ct, string ti, string priority) 
        { 
            return SendScheSMS(sn, mn, ct, ti, priority); 
        }

        #endregion 
    }

相关的测试代码:

      static void Main(string[] args) 
       { 
           //相关的测试代码 
           //调用外观对象中的服务 
           MessageHelper.instance.SendSMS1("", "", "", ""); 
       }

      2、我们在架构设计的过程中,一次的功能访问可能需要同时的调用很多个对象,那么如果我们在服务调用的时候,能够在应用程序调用中一次就能完

成所有要同时调用的对象那该多好啊,外观模式无疑是最好的原则,特别是在分布式应用中,通过远程调用服务,通过外观模式降低应用程序与服务的交互

次数,同时可以降低应用程序的复杂性。外观模式+DTO,提供远程服务调用的性能,这些都是好的设计方式。我们来看看简单的示例吧,我想我们更

能了解其中的奥妙。看图说话吧,我们这里以一次远程同步服务为例。

未使用外观模式前:

设计模式——外观模式

一个简单的同步服务,由于应用程序在这次服务中为了完成同步操作,必须进行3次远程连接来进

行把3个对象进行同步,那么如果我们使用外观对象之后呢,我们只需要访问一次即可完成3个对象的同步。这无疑提高了系统的性能和效率。

设计模式——外观模式

并且通过DTO来进行传输的话,可以提供远程服务调用的访问此时和效率。