目录

常用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();

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