常用C#设计模式(下)

【代理模式】

描述:给某一个对象提供一个代理,并由代理对象控制对原对象的引用。

在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。举几个例子,用户提供食材和菜名,“不想”自己做菜,给厨师,厨师就是一个代理。国内用户访问facebook会被墙,代理可以绕开GFW并将请求结果返回。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public interface IRequest
{
// Methods
string Request(string sourceIp,string targetIp);
}

class GFW : IRequest
{
public string Request(string sourceIp, string targetIp)
{
if (sourceIp=="国内ip" && targetIp == "敏感ip")
{
return "404错误";
}
else
{
return "请求成功";
}
}
}

class Proxy : IRequest
{
GFW gfw = new GFW();

public string Request(string sourceIp, string targetIp)
{
sourceIp = "代理ip";
return gfw.Request(sourceIp, targetIp);
}
}

//调用
GFW gfw = new GFW();
Console.Write(gfw.Request("国内ip", "敏感ip"));

//Proxy p = new Proxy();
//Console.Write(p.Request("国内ip", "敏感ip"));

简单来说代理模式能够保护请求者信息,能够解决请求者不能直接获取目标信息的问题。

【观察者模式】

描述:当事物的状态发生改变时,观察者通知主体。

熟悉mvvm的人肯定对观察者模式有比较深入的了解了,就是后台处理事务,然后通知用户界面显示。可以理解成一个监听的过程。但从oop角度来说,要将观察者和主体分离开来从而提高程序可维护性。在这个模式中观察者都会给其他主体的对象提供一个接口,通过这个接口,就可以让观察者获知该对象的状态。举个例子,老板不在办公室,所以有的人在炒股,有的人在看视频,有的人在玩游戏,然后前台放哨,只要老板回来,就通知大家。然后炒股的关闭看盘软件,看视频的退出浏览器,玩游戏的下线。

例子:

如果不用观察者模式,最原始的办法可能是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Receptionist
{
public void BossComeBack()
{
Console.Write("老板回来了!");
new Share().CloseSoftWare();
new Video().CloseWebBrowser();
new Game().Logoff();
}
}
public class Share
{
public void CloseSoftWare()
{
Console.Write("关闭软件!");
}
}

public class Video
{
public void CloseWebBrowser()
{
Console.Write("退出浏览器!");
}
}

public class Game
{
public void Logoff()
{
Console.Write("游戏下线!");
}
}

这种方法从oop角度来说是很混乱且不利于扩展,如果还有其他同事需要前台通知,就要不断的修改Receptionist的BossComeBack方法。这违背了开闭原则。

下面用观察者模式来搭建这个模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
interface ISubject
{
void Notify();//通知观察者
void Regiester(IObservable o);//注册
void UnRegiester(IObservable o);//取消注册
}

class Receptionist : ISubject
{
private IList<IObservable> observers = new List<IObservable>();
public void Notify()
{
foreach (IObservable o in observers)
{
o.Action();
}
}
public void Regiester(IObservable o)
{
if (o != null || !observers.Contains(o))
{
observers.Add(o);
}
}
public void UnRegiester(IObservable o)
{
if (observers != null && observers.Contains(o))
{
observers.Remove(o);
}
}
public void BossComeBack()
{
Console.WriteLine("老板回来了!");
Notify();
}
}

interface IObservable
{
void Action();//观察者对变动对应的操作
}

class Share : IObservable
{
public void Action()
{
Console.WriteLine("关闭软件!");
}
}
class Video : IObservable
{
public void Action()
{
Console.WriteLine("退出浏览器!");
}
}

class Game : IObservable
{
public void Action()
{
Console.WriteLine("游戏下线!");
}
}

//调用
Video v = new Video();
Game g = new Game();
Share s = new Share();
Receptionist r = new Receptionist();
r.Regiester(v);
r.Regiester(g);
r.Regiester(s);
r.BossComeBack();

上面这个例子满足了开闭原则,同时观察者和主体之间通过注册和撤销注册来建立关联。也满足了高内聚低耦合的特性。

常用C#设计模式(下)

https://wurang.net/csharp_design_pattern_c/

作者

Wu Rang

发布于

2014-03-18

更新于

2021-12-06

许可协议

评论