02.06 外观模式

设计模式——外观模式

需求

.NET程序员大多使用过System.SqlClient、System.OracleClient、System.OleDb,尽管针对的数据库不同,这些类库体系都是实现访问数据库功能。尽管体系结构很相似,使用方法很相似,但是各对应类名称的不同,还是需要各写各的,如果能进行封装,形成一套统一的方法调用就好了。

从理论层次来说就是,在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,而导致客户程序随着子系统的变化而变化。那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子系统与客户程序之间的依赖解耦?这就是要说的外观模式(Façade Pattern)。

定义

意图:外部与子系统的通信必须通过统一的门面对象进行。外观模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。即当子系统复杂或者繁锁时,我们让子系统提供一个窗口,程序中称为接口,其它程序或者对象就通过这个窗口(接口)与此子系统联系。这样就简化了子系统的使用。

  

外观模式由2部分组成:(1)外观类(Facade),定义外观规格;(2)其它需要封装的子系统(SubSystem)。

外观模式又叫门面模式。门面是一个类,它把客户对象所需要的子系统的功能简化到简单的接口上,客户对象不直接与子系统内部的对象打交道,而是简单地调用门面对象所提供的接口,门面对象再去调用子系统内部的具体功能。

由于各子系统的使用简化成一个统一的外观类,所以外观类常常用单例或者静态来实现。

案例

     class Program

    {

        static voidMain(string[] args)

        {

            // 客户程序

            Customer cust = new Customer("张三");

            MortgageFacade mortgage = new MortgageFacade();

            bool isEligible = mortgage.IsEligible(cust, 10000);

            string result = isEligible ? "审查完成:{0}具有贷款资格!" : "审查完成:{0}不具有贷款资格!";

            Console.WriteLine(result, cust.Name);

        }

    }

    // 一个需要贷款的客户

    public class Customer

    {

        public Customer(string name) { this._Name = name; }

        private string _Name;

        public string Name { get { return _Name; } }

    }

    // 三个需要封装的子系统

    // 银行子系统

    public class Bank

    {

        public bool HasSufficientSavings(Customer c, int amount)

        {

            Console.WriteLine("\t检查{0}银行存款... ", c.Name);

            return true;

        }

    }

    // 信用子系统

    public class Credit

    {

        public bool HasGoodCredit(Customer c)

        {

            Console.WriteLine("\t检查{0}的信用记录...", c.Name);

            return true;

        }

    }

    // 贷款子系统

    public class Loan

    {

        public bool HasNoBadLoans(Customer c)

        {

            Console.WriteLine("\t检查{0}贷款记录...", c.Name);

            return true;

        }

    }

    // 外观类

    public class MortgageFacade

    {

        private Bank bank = new Bank();

        private Loan loan = new Loan();

        private Credit credit = new Credit();

        // 是否合格的贷款客户

        public bool IsEligible(Customer cust, int amount)

        {

            Console.WriteLine("开始审查{0}的贷款资格:", cust.Name);

            if (!bank.HasSufficientSavings(cust, amount)) return false;

            if (!loan.HasNoBadLoans(cust)) return false;

            if (!credit.HasGoodCredit(cust)) return false;

            return true;

        }

    }

优缺点

优点:外观模式通过提供一个统一的对外接口,避免了外部系统和子系统之间的直接联系,从而降低了系统间的依赖,也降低了常常需要使用多个子系统而导致的复杂度。

缺点:限制了外部系统对子系统调用的灵活性,只能按照外观类中提供的方式来调用子系统,所以需要精心设计外观系统。

适用场景

当一个或多个复杂的系统需要对外提供接口时,就需要对外提供的接口统一封装在一个外观类里,供外系统使用。

外观模式注重的是简化接口,它更多的时候是从架构的层次去看整个系统,而并非单个类的层次。如果应用需要,它并不限制它们使用子系统类。因此你可以在系统易用性与通用性之间选择。

补充

原文地址:https://www.cnblogs.com/sagahu/p/2711199.html