C# 設計模式之空對象模式


 最近看了不少的書籍和視頻等相關資料,決定自己邊學習邊寫一下個人對設計模式的理解,如果有不對的請大家多多指正。

今天先說說我個人覺得最簡單的設計模式 -- [空對象模式]

空對象模式可以減少客戶端對對象判斷是否為空的重復操作,也可以減少異常發生的情況【如果客戶端調用程序忘記了檢查對象是否為空,而直接訪問對象中的數據,則有可能會報出異常,影響程序運行】。

廢話不說了,先上我寫的代碼,下面是未運用空對象模式之前的示例代碼:

 

 

要返回的實體代碼,Person.cs:

namespace NullObjectPattern
{
    public class Person
    {
        /// <summary>
        /// 用戶ID
        /// </summary>
        public int Id { set; get; }

        /// <summary>
        /// 用戶名字
        /// </summary>
        public string Name { set; get; }

         /// <summary>
        /// 學習
        /// </summary>
        public void Study()
        {
            Console.WriteLine("{0}學習中……",Name);
        }

    }
}

 

 

中間訪問層代碼,PersonService.cs:

namespace NullObjectPattern
{
    public class PersonService
    {
        /// <summary>
        /// 獲取用戶信息方法
        /// </summary>
        /// <param name="id">用戶id</param>
        /// <returns>用戶信息對象實體</returns>
        public Person GetPersonById(int id)
        {
            Person p = null;
            if (id == 1)
            {
                p = new Person
                {
                    Id = 111,
                    Name = "小明"
                };
            }
            return p;
        }

    }
}

 

 

程序主入口代碼,Program.cs:

using System;

namespace NullObjectPattern { class Program { static void Main(string[] args) { var service = new PersonService(); var person = service.GetPersonById(2); Console.Write("用戶的名字為:{0}",person.Name); Console.Read(); } } }

 

輸出的結果:

主程序入口代碼改造后,Program.cs:

using System;

namespace NullObjectPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                var service = new PersonService();
                var person = service.GetPersonById(2);
                if (person == null)
                    Console.WriteLine("用戶的名字為:未知");
                else
                    Console.WriteLine("用戶的名字為:{0}", person.Name);
                if (person != null)
                {
                    person.Study();
                }
            
            Console.Read();
        }
    }
}

  

輸出的結果:

 

 

按照上面的代碼來寫的話,我每次獲取用戶的詳細信息是不是都需要判斷用戶的對象是否為空?這樣會不會有重復的代碼?影響代碼質量?

我們的空對象模式就解決了這個問題。

 增加一個抽象類,Human.cs:

    public abstract class Human
    {
        /// <summary>
        /// 用戶ID
        /// </summary>
        public int Id { set; get; }

        /// <summary>
        /// 用戶名字
        /// </summary>
        public string Name { set; get; }

        /// <summary>
        /// 學習
        /// </summary>
        public abstract void Study();

    }

 

 

然后讓真正的實體類和空對象類同時繼承這個抽象類:

    public class Person: Human
    {
        /// <summary>
        /// 實現方法的默認實現
        /// </summary>
        public override void Study()
        {
            Console.WriteLine("{0}學習中……",Name);
        }
    }

 

 

空對象類:

    public class NullPerson : Human
    {

        public NullPerson()
        {
            Id = 0;
            Name = "未知";
        }

        /// <summary>
        /// 實現方法的默認實現
        /// </summary>
        public override void Study()
        {
            Console.WriteLine("無法學習");
        }
    }

 

 中間訪問層,PersonService.cs:

 

namespace NullObjectPattern
{
    public class PersonService
    {
        /// <summary>
        /// 獲取用戶信息方法
        /// </summary>
        /// <param name="id">用戶id</param>
        /// <returns>用戶信息對象實體</returns>
        public Human GetPersonById(int id)
        {
            Human human = null;
            if (id == 1)
            {
                human = new Person
                {
                    Id = 111,
                    Name = "小明"
                };
            }
            else
            {
                human = new NullPerson();
            }
            return human;
        }
    }
}

主程序代碼:

    class Program
    {
        static void Main(string[] args)
        {
             {
                Console.WriteLine("空對象模式******************************");
                var service = new PersonService();
                var person = service.GetPersonById(2);
                Console.WriteLine("用戶的名字為:{0}", person.Name);
                person.Study();
            }
            Console.Read();
        }
    }

 

 

輸出的結果:

 

 

 

 

 總結:

   綜上所述,空對象模式能減少客戶端的工作量,把判斷返回對象是否為空的邏輯交給了中間層,也減少客戶端發生異常的可能性,對程序的性能進行了優化。

缺點:就是每一個要返回的真實的實體都要建立一個對應的空對象模型,那樣會增加實體層的文件數量。個人覺得這種模式在工程或者實體文件很少的情況下可以適當使用,不建議在實際工作開發中大量的使用。

謹慎使用即可。

 


免責聲明!

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



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