[设计模式] 装饰器模式

时间:2022-12-05 18:09:57

一、装饰器模式

  在软件开发过程中,由于需求的改动,可能面临对某个或某些对象新增一些新的功能的需求。根据开闭原则,新增功能我们也不能直接去修改

原有的类,而如果使用继承的方式去实现,可能出现“子类爆炸”的问题,这个时候就可以使用到 装饰器模式。

  装饰器模式:允许向一个现有的对象添加新的功能,同时又不改变这个现有对象的结构。属于结构型设计模式,它是作为现有类的一种包装。

首先会创建一个装饰类,用来包装原有的类,并在保持类的完整性的前提下,提供额外的功能。

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.结束

  以上就是本次的全部内容,通过一个简单的案例讲解了一下装饰器模式。如有不同见解,可以评论一起探讨。