設計模式----裝飾器模式

守望陽光01發表於2019-04-05

       今天來學習分析下裝飾器模式,首先我們分析它的名字應該要知道這個模式的作用應該就是類似我們用裝飾品一樣,隨用隨取的特點。發揮你的想象,如果我們寫的程式能有這樣的特點,以後業務需要更改的時候是不是再也不用埋頭寫BUG了,只需要把不要的裝飾換下來就好了,廢話不多說,下面讓我們看看是怎麼實現裝飾器模式的吧。

        首先,依舊是老規矩,設定一個場景:學生購買課程課後練習鞏固,首先,學生需要購買課程,然後學習課程,接著課後練習,再然後就提交作業等一系列動作;這裡主體就是學生,接下來,我們就應該幹嘛呢,沒錯,當然是抽象一個學生類出來,請看程式碼:

 public abstract class AbstractStudent
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public abstract void Study();

    }

        很簡單,AbstractStudent類包含兩個屬性和一個抽象方法,這就是我們抽象出來的學生類。接下來,我們就要來建立我們今天的重頭類了裝飾器的基類,看程式碼

/// <summary>
    /// 裝飾器的基類
    /// 也是一個學員  繼承了抽象類
    /// </summary>
    public class BaseStudentDecorator : AbstractStudent
    {
        private AbstractStudent _Student = null;
        public BaseStudentDecorator(AbstractStudent student)
        {
            this._Student = student;
        }

        public override void Study()
        {
            this._Student.Study();
            //Console.WriteLine("**********");
            //基類裝飾器必須是個空的行為
        }
    }

        這個裝飾器基類它繼承了我們開始建立的抽象學生類,所以它也是一個學生類,這個BaseStudentDecorator類有一個建構函式和重寫了AbstractStudent類的Study方法,這裡利用建構函式注入了一個AbstractStudent物件,然後重寫了AbstractStudent抽象類的方法Study去呼叫它的Study,到這估計迷糊了,為什麼要這樣做呢,繞來繞去幹嘛呢這是,不急,我們接著往下看

public class StudentVip : AbstractStudent
    {
        public override void Study()
        {
            Console.WriteLine("{0}是VIP學生,正在學習vip課程 ", base.Name);
        }
    }

        這裡我們建立了一個StudentVip類,它繼承AbstractStudent抽象學生類,並且重寫Study方法,實現自己的邏輯,到這裡就結束了嗎,那這個裝飾器模式豈不是廢柴嗎(哈哈),彆著急,我們接著往下看

public class StudentPreivew : BaseStudentDecorator
    {
        public StudentPreivew(AbstractStudent student) : base(student)//表示父類的建構函式
        {
            //this._Student = student;
        }

        public override void Study()
        {
            Console.WriteLine("預習");
            base.Study();
        }
    }

        這裡就開始變化了,我們建立了一個StudentPreivew類,注意,它實現的是BaseStudentDecorator類,同樣它重寫Study方法,這樣,我們就實現了裝飾器模式了,??什麼,這就實現了,我還沒有明白是怎麼回事呢,搞什麼呢。。。所有的骨架我們基本都學完了,現在就讓我們看看上端是如何呼叫實現裝飾的

class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("--------------------------");
                AbstractStudent abstractStudent = new StudentVip()
                {
                    Id = 9,
                    Name = "jjjj"
                };
     
                Console.WriteLine("*************************");
                {
                    abstractStudent = new StudentPreivew(abstractStudent);//預習
abstractStudent.Study();
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }

       首先,我們建立一個Vip學生,給它分配號碼取名字。這裡有個知識點,抽象類是不能通過New關鍵字例項化的,介面也是一樣,知識點get到了沒有。接下來我們例項化了一個StudetPreivew,傳入我們之前建立的AbstractStudent類,為什們呢,因為我們的建構函式需要一個AbstractStudent物件才能建立我們的StudentPreivew物件,不然是無法建立StudentPreivew物件的,現在,讓我們執行程式來看看執行結果。

       我們可以看到,我們成功的把預習這個動作成功的裝飾上去了,如果你願意,我們可以新增更多的動作和邏輯,如果你不願意,只要不例項化StudentPreivew物件就可以,這樣是不是就是達到了裝飾的效果呢,想用的時候new它,不想用的時候不new它,注意,我們所有的操作都是在最上層修改,根本不用關心底層程式碼,看完這個裝飾器模式,是不是有種似曾相識的感覺呢,哈哈,對,和之前說的策略模式很相像對吧,策略模式是有一個上下文類,通過上層傳入需要的實際策略類,然後呼叫上下文類方法去實現,我們今天所說的裝飾器是例項所需要的動作類傳入主體,實際動作類繼承BaseStudentDecorator類,而BaseStudentDecorator類又繼承AbstractStudent類,最後我們上層呼叫的方法是AbstractStudent類的Study方法,所以,可以這麼說,孫子通過父親呼叫爺爺的方法,這句話就是我們今天所講的裝飾器模式的精髓(O(∩_∩)O哈哈~)。。。

 

相關文章