[設計模式] 裝飾器模式

_冬眠發表於2022-12-05

一、裝飾器模式

  在軟體開發過程中,由於需求的改動,可能面臨對某個或某些物件新增一些新的功能的需求。根據開閉原則,新增功能我們也不能直接去修改

原有的類,而如果使用繼承的方式去實現,可能出現“子類爆炸”的問題,這個時候就可以使用到 裝飾器模式。

  裝飾器模式:允許向一個現有的物件新增新的功能,同時又不改變這個現有物件的結構。屬於結構型設計模式,它是作為現有類的一種包裝。

首先會建立一個裝飾類,用來包裝原有的類,並在保持類的完整性的前提下,提供額外的功能。

1.首先建立一個User類 

public class User
{
    public string UserName{get;set;}
    public string Password{get;set;}
}

 

2.建立一個使用者服務介面IUserService,裡面有一個RegisterUser方法用來註冊一個使用者

public interface IUserService
{
    void RegisterUser(User user);
}    

3.建立一個類實現IUserService介面

public class UserService:IUserService
{
    public void RegisterUser(User user)
    {
        Console.WriteLine($"{user.UserName}註冊成功");
    }
}        

4.在控制檯Main方法中呼叫

class Program
    {
        static void Main(string[] args)
        {
            IUserService service = new UserService();
            var user = new User("jyq", "123456");
            service.RegisterUser(user);
            Console.ReadKey();
        }
    }

  執行結果:

5.現在要新增一個需求,要求在註冊成功之後列印日誌。這時我們再建立一個裝飾器類:UserDecorator

public class UserDecorator : IUserService
    {
        private readonly IUserService _userService;

        public UserDecorator(IUserService userService)
        {
            _userService = userService;
        }
        public void RegisterUser(User user)
        {
            _userService.RegisterUser(user);

            var path = Environment.CurrentDirectory + "\\log.txt";
            using(var stream = new FileStream(path, FileMode.OpenOrCreate,FileAccess.Write))
            {
                string msg = $"{DateTime.UtcNow:d}:{user.UserName}註冊成功";
                byte[] buffer = Encoding.UTF8.GetBytes(msg);
                stream.Write(buffer, 0, buffer.Length);
                stream.Close();
            }
        }
    }

6.在Main函式中呼叫就變成了這樣 

class Program
    {
        static void Main(string[] args)
        {
            IUserService service = new UserService();
            var user = new User("jyq", "123456");
            var decorator = new UserDecorator(service);
            decorator.RegisterUser(user);
            Console.ReadKey();
        }
    }

7.看一下執行結果

  這樣就透過裝飾器模式在不改變原有物件結構的前提下實現了新的需求功能。

9.結束

  以上就是本次的全部內容,透過一個簡單的案例講解了一下裝飾器模式。如有不同見解,可以評論一起探討。

相關文章