C#委托
来源:互联网 发布:linux显示隐藏文件 编辑:程序博客网 时间:2024/06/06 09:29
学习是一个过程,再一次看到委托,感觉理解比曾经多了一点点,或许距离真正的理解还有很大的距离,但是距离却在缩短.
先看一下下面一个登录的小例子
namespaceConsoleApplication1{ class User { public string Name { get; set; } public string Password { get; set; } } class UserIdentify { public void Login(User user) { if (user.Name == "Bema") { Show("登录成功,登录信息已经保存到数据库"); } else { Show("登录失败!"); } } private void Save(string message) { Console.WriteLine(message); } }}
UserIdentify类封装用户登录的逻辑,这里只有一个需求,那就是登录成功给出提示.
客户端的代码为
class Program { static void Main(string[] args) { User user = new User { Name = "Bema", Password = "123" }; UserIdentify identify = new UserIdentify(); identify.Login(user); Console.ReadLine(); } }
然而这样的设计肯定是无法满足用户的需求的,用户或许希望能够将登录信息保存到文本文件,而不仅仅是数据库。如果我们仅仅修改Save方法的实现,那么用户需求再次改变时我们该如何处理呢?难道要无休止地修改Save方法吗?
既然Save方法是变化的根源,我们自然会想到将其进行封装。我们创建一个名为IStrategy 的接口。
interface IStrategy
{
void Save();
}
并创建两个实现了IStrategy 的类,DBSave和TextSave,分别用来向数据库中存入信息和向文本文件中存入信息.
class DBSave : IStrategy { public void Save() { Console.WriteLine("向数据库中插入成功"); } } class TextSave : IStrategy { public void Save() { Console.WriteLine ("向文本文件插入成功"); } }
在UserService类中添加一个IStrategy类型的属性SaveStrategy。
class UserService { public IStrategy SaveStrategy { get; set; } public UserService() { SaveStrategy = new DBSave(); } public void Login(User user) { if (user.Name == "Bema") { SaveStrategy .Save(); } else { SaveStrategy .Save(); } } }
客户端代码变为如下形式。
class Program { static void Main(string[] args) { User user = new User { Name = "Bema", Password = "123" }; UserService service = new UserService { SaveStrategy = new TextSave() }; service.Login(user); Console.ReadLine(); } }
在声明UserService的时候,还可以将SaveStrategy设置为TextSave。这样在UserService进行逻辑处理时,使用的SaveStrategy即为TextSave,信息将被保存到文本文件中。这里运用了一个策略模式使得代码更加的灵活.但是虽然大大的提高了灵活性,但仍然没能满足客户的需求,为什么呢?
使用委托
1.用户也许会希望另一种存储方式。当然,你可以通过在客户代码处扩展IStrategy来实现自己的日志记录方式
但这种方案是否过于复杂呢?如果用户希望再用一种存储方式,是否需要逐个创建新类呢?并且这样的实现是否与客户端的耦合过于紧密呢?并且代码过于复杂且难以重用;
2. 用户也许会希望同时使用多种方式来存储数据。比如,同时向DB2、文本文件、Excel表格和word中存储数据。你当然可以在UserService中维护一个List<ILog>,但这时UserService的职责过多,显然违反了SRP。
下面介绍本文的主角:委托。
我们首先来创建一个名为Save的委托。
public delegate void Save();
然后在UserService类中添加一个Log委托类型的属性SaveDelegate。
class UserService
{
public SaveSaveDelegate { get; set; }
// …
}
在客户端,我们直接声明两个静态方法,它们没有返回值。
static void SaveToDB() { Console.WriteLine("向DB中存储数据成功"); } static void SaveToText(string message) { Console.WriteLine("向Text中存储数据成功");}
客户端声明UserService的代码变为
static void Main(string[] args) { User user = new User { Name = "Bema", Password = "123" }; UserService service = new UserService(); service.SaveDelegate = SaveToConsole; service.SaveDelegate += SaveToText; service.Login(user); Console.ReadLine(); }
或许上面的例子阐述委托和接口有些过于牵强,事实上有些时候的确很难选择使用接口还是委托。但所有委托适用的情况同样可以使用包含单一方法的接口来实现的。在某种程度上,可以说委托是接口(仅定义了单一方法)的一种轻量级实现,它更灵活,也更方便。
- C#委托-委托概述
- C#委托
- C#委托
- C#委托
- c#委托
- C# 委托
- C#委托
- C# 委托
- c#委托
- C#委托
- c#委托
- C#委托
- C# - 委托
- C#委托
- C#委托
- C#委托
- C# 委托
- c#委托
- 绑定和分配mmap内核空间(bind_ring)--(七)
- nginx 多站点配置方法集合
- Deprecated: Function ereg() is deprecated in 解决方案
- JAVA存取PostgreSQL大对象类型oid
- 和清科技今天在这里安家,欢迎大家!!
- C#委托
- 解决vs2012解决方案中的一个或多个项目由于以下原因未能加载
- [Hadoop源码解读](四)MapReduce篇之Counter相关类
- mmap内存映射---(八)九
- java中interface与abstract的区别
- spring下配置dbcp,c3p0,proxool
- 对二维数组的理解
- 新版谷歌地图正式推出
- A few comments from leads for Power BI GA