設計模式學習筆記-外觀模式


1. 概述

  為子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。

2. 模式中的角色

  2.1 外觀類(Facade):外觀類知道哪些子系統類負責處理請求,將客戶的請求代理給恰當的子系統對象。

  2.2 子系統類集合(SubSystem Classes):子系統類集合實現了子系統的功能,處理外觀類對象指派的任務。

3. 模式解讀

  3.1 外觀模式的類圖

  

  3.2 外觀模式的代碼實現

    /// <summary>
    /// 子系統中的一個類
    /// </summary>
    public class SubSystemOne
    {
        public void MethodeOne()
        {
            Console.WriteLine("Sub System first method.");
        }
    }

    /// <summary>
    /// 子系統中一個類
    /// </summary>
    public class SubSystemTwo
    {
        public void MethodTwo()
        {
            Console.WriteLine("Sub System second method.");
        }
    }

    /// <summary>
    /// 子系統中一個類
    /// </summary>
    public class SubSystemThree
    {
        public void MethodThree()
        {
            Console.WriteLine("Sub System third method.");
        }
    }

    /// <summary>
    /// 子系統中一個類
    /// </summary>
    public class SubSystemFour
    {
        public void MethodFour()
        {
            Console.WriteLine("Sub System fourth method.");
        }
    }

    /// <summary>
    /// 外觀類
    /// </summary>
    public class Facade
    {
        private SubSystemOne one;
        private SubSystemTwo two;
        private SubSystemThree three;
        private SubSystemFour four;

        public Facade()
        {
            one = new SubSystemOne();
            two = new SubSystemTwo();
            three = new SubSystemThree();
            four = new SubSystemFour();
        }

        public void MethodA()
        {
            Console.WriteLine("\nMethod group A----");
            one.MethodeOne();
            two.MethodTwo();
            four.MethodFour();
        }

        public void MethodB()
        {
            Console.WriteLine("\nMethod group B----");
            two.MethodTwo();
            three.MethodThree();
        }
    }

 

    3.3 客戶端代碼

    class Program
    {
        static void Main(string[] args)
        {
            // 由於Facade的作用,客戶端可以根本不知道子系統類的存在
            Facade facade = new Facade();
            facade.MethodA();
            facade.MethodB();

            Console.Read();
        }
    }

    運行結果

  

4. 模式總結

  4.1 優點

    4.1.1 Facade模式降低了客戶端對子系統使用的復雜性。

    4.1.2 外觀模式松散了客戶端與子系統的耦合關系,讓子系統內部的模塊能更容易擴展和維護。

    4.1.3 通過合理使用Facade,可以幫助我們更好的划分訪問的層次。

  4.2 缺點

    過多的或者是不太合理的Facade也容易讓人迷惑,到底是調用Facade好呢,還是直接調用模塊好。

  4.3 適用場景

    4.3.1 需要將設計進行分層時考慮Facade模式。

    4.3.2 在開發階段,子系統往往因為重構變得越來越復雜,增加外觀模式可以提供一個簡單的接口,減少它們之間的依賴。

    4.3.3 在維護一個遺留的大型系統時,可以這個系統已經非常難以維護和擴展,可以為新系統開發一個Facade類,來提供設計粗糙或高度復雜的遺留代碼的比較清晰簡單的接口,讓新系統與Facade對象交互,Facade與遺留代碼交互所有復雜的工作。

5. 應用舉例:分層開發中,對數據訪問層我們增加DataAccess作為對外的接口來操作數據庫子系統。

  5.1 實現類圖

  

  5.2 實現代碼

    public class Employee
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public Salary Salary { get; set; }
    }

    public class Salary
    {
        public DateTime From { get; set; }
        public DateTime To { get; set; }
        public decimal Amount { get; set; }
    }

    public class EmployeeDataAccess
    {
        public void SaveEmployee(Employee employee)
        {
            Console.WriteLine("Save employee to database.");
        }

        public void DeleteEmployee(Employee employee)
        {
            Console.WriteLine("Remode employee from database.");
        }
    }

    public class SalaryDataAccess
    {
        public void SaveSalary(Salary salary)
        {
            Console.WriteLine("Save salary to database.");
        }

        public void DeleteSalary(Salary salary)
        {
            Console.WriteLine("Remove salary from database.");
        }
    }

    /// <summary>
    /// DataAccess為客戶端提供一個簡單的接口
    /// </summary>
    public class DataAccess
    {
        private EmployeeDataAccess employeeDataAccess = new EmployeeDataAccess();
        private SalaryDataAccess salaryDataAccess = new SalaryDataAccess();

        public void SaveEmployee(Employee employee)
        {
            // 先保存員工基本信息
            employeeDataAccess.SaveEmployee(employee);

            // 保存員工薪水信息
            salaryDataAccess.SaveSalary(employee.Salary);
        }

        public void RemoveEmployee(Employee employee)
        {
            // 先刪除員工薪水信息
            salaryDataAccess.DeleteSalary(employee.Salary);

            // 刪除員工基本信息
            employeeDataAccess.DeleteEmployee(employee);
        }
    }

  5.3 客戶端代碼

    class Program
    {
        static void Main(string[] args)
        {
            DataAccess.DataAccess dataAccess = new DataAccess.DataAccess();
            DataAccess.Employee employee = new DataAccess.Employee() { Salary = new DataAccess.Salary(), Name = "Wang Kevin", Age = 22 };

            dataAccess.SaveEmployee(employee);
            dataAccess.RemoveEmployee(employee);

            Console.Read();
        }
    }

  運行結果

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM