开始委托之旅 委托与接口

📅 2026/7/6 3:09:56 👁️ 阅读次数 📝 编程学习
开始委托之旅 委托与接口

好了,下面让我从一个示例开始,一步一步引入委托的概念。

从示例开始

假设一个系统的用户登录模块有如下所示的代码

class User { public string Name { get; set; } public string Password { get; set; } } class UserService { public void Register(User user) { if (user.Name == "Kirin") { Log("注册失败,已经包含名为" + user.Name + "的用户"); } else { Log("注册成功!"); } } privte void Log(string message) { Console.WriteLine(message); } }

UserService类封装用户登录的逻辑,并根据不同的登录情况向控制台打印不同的日志内容。当程序关闭时,所记录的日志自然也随之消失。

客户端的代码为

class Program { static void Main(string[] args) { User user = new User { Name = "Kirin", Password = "123" }; UserService service = new UserService(); service.Register(user); Console.ReadLine(); } }

使用策略模式

然而这样的设计肯定是无法满足用户的需求的,用户肯定希望能够查看以前的日志记录,而不仅仅是程序打开以后的内容。如果我们仅仅修改Log方法的实现,那么用户需求再次改变时我们该如何处理呢?难道要无休止地修改Log方法吗?

既然日志记录的方式是变化的根源,我们自然会想到将其进行封装。我们创建一个名为ILog的接口。

interface ILog { void Log(string message); }

并创建两个实现了ILog的类,ConsoleLog和TextLog,分别用来向控制台和文本文件输出日志内容。

class ConsoleLog : ILog { public void Log(string message) { Console.WriteLine(message); } }
class TextLog : ILog { public void Log(string message) { using (StreamWriter sw = File.AppendText("log.txt")) { sw.WriteLine(message); sw.Flush(); sw.Close(); } } }

在UserService类中添加一个ILog类型的属性LogStrategy。

class UserService { public ILog LogStrategy { get; set; } public UserService() { LogStrategy = new ConsoleLog(); } public void Register(User user) { if (user.Name == "Kirin") { LogStrategy.Log("注册失败,已经包含名为" + user.Name + "的用户"); } else { LogStrategy.Log("注册成功!"); } } }

客户端代码变为如下形式。

class Program { static void Main(string[] args) { User user = new User { Name = "Kirin", Password = "123" }; UserService service = new UserService { LogStrategy = new TextLog() }; service.Register(user); Console.ReadLine(); } }

在声明UserService的时候,还可以将将LogStrategy设置为TextLog。这样在UserService进行逻辑处理时,使用的LogStrategy即为TextLog,日志将输出到文本文件中。

我们在干什么?我们在重构。重构的结果是什么?重构的结果是实现了一个简单的策略模式。

使用委托

然而策略模式仍然不能满足客户的需求,这是为什么呢?

1.用户也许会希望自定义Log的实现。当然,你可以通过在客户代码处扩展ILog来实现自己的日志记录方式。如

class TextBoxLog : ILog { private TextBox textBox; public TextBoxLog(TextBox textBox) { this.textBox = textBox; this.textBox.Multiline = true; } public void Log(string message) { textBox.AppendText(message); textBox.AppendText(Environment.NewLine); } }