CSharp-Design-Pattern

前言

创建型

结构性

行为型

Simple Factory

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace CsharpDesignPattern.SimpleFactory
{
///简单工厂
/// 设计实现,一个工厂能生产A,也能生产B,根据传入的参数
/// 1 是面向用户的类Factory
/// 2 是该工厂生产所有产品的公共接口/方法 Product
/// 3 则是具体的生产方法类ProductA,继承Product
///
/// https://blog.csdn.net/heyangyi_19940703/article/details/51181583

public class SimpleFactory
{
public static Product createProduct(string productType)
{
if (productType == "A")
{
return new productA ();
}
if (productType == "B")
{
return new productB ();
} else
return null;
}
}
//这里用interface也可以
public abstract class Product
{
public abstract void UseProduct();
}

public class productA:Product
{
public productA()
{
Debug.Log ("create product A.");
}
public override void UseProduct ()
{
Debug.Log ("use product A.");
}
}

public class productB:Product
{
public productB()
{
Debug.Log ("create product B.");
}
public override void UseProduct ()
{
Debug.Log ("use product B.");
}
}
////--------------------------------------------------------------------
// Debug.Log ("Test Simple Factory:");
// Product myproduct;
// myproduct = SimpleFactory.createProduct ("A");
// myproduct.UseProduct ();
// myproduct = SimpleFactory.createProduct ("B");
// myproduct.UseProduct ();

}

Factory

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
namespace CsharpDesignPattern.Factory
{
/// <summary>
/// Factory
/// 解决:实现一个工厂,要求能在随时添加新的生产方法。比如Simple Factory中要加新方法就只能修改Factory中的if语句。
/// 案例
/// 1 抽象工厂Factory
/// 2 具体工厂AB分别只负责A或者B的生产
/// 3 抽象产品
/// 4 具体产品生产
/// https://www.cnblogs.com/zhili/p/FactoryMethod.html
/// https://blog.csdn.net/heyangyi_19940703/article/details/51188966
/// </summary>

//产品
public abstract class Product
{
public abstract void UseProduct();
}

public class productA:Product
{
public override void UseProduct()
{
Debug.Log ("use product A.");
}
}
public class productB:Product
{
public override void UseProduct()
{
Debug.Log ("use product B.");
}
}

//工厂
public abstract class Factory
{
public abstract Product createProduct();
}
public class FactoryA:Factory
{
public override Product createProduct()
{
return new productA ();
}
}
public class FactoryB:Factory
{
public override Product createProduct()
{
return new productB ();
}
}
////--------------------------------------------------------------------
// Debug.Log ("Test Factory:");
// Factory createAFactory = new FactoryA ();
// Factory createBFactory = new FactoryB ();
// Product myproductA = createAFactory.createProduct ();
// myproductA.UseProduct ();
// Product myproductB = createBFactory.createProduct ();
// myproductB.UseProduct ();

}

AbstractFactory

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
76
77
78
79
80
81
82
83
84
85
86
namespace CsharpDesignPattern.AbstractFactory
{
/// <summary>
/// Abstract Factory
/// 解决:每个工厂可以多元化地生产不同的产品,工厂A生产A1,A2,工厂B生产B1,B2
/// 1 两个抽象的产品A B,具体的产品A1A2B1B2
/// 2 抽象工厂,抽象的生产AB的方法
/// 3 两个具体的工厂,均可以生产各自的AB
/// </summary>

public abstract class ProductTypeA
{
public abstract void UseProductA ();
}
public abstract class ProductTypeB
{
public abstract void UseProductB ();
}

public class ProductA_1:ProductTypeA
{
public override void UseProductA()
{
Debug.Log ("Use product A1.");
}
}
public class ProductB_1:ProductTypeB
{
public override void UseProductB()
{
Debug.Log ("Use product B1.");
}
}
public class ProductA_2:ProductTypeA
{
public override void UseProductA()
{
Debug.Log ("Use product A2.");
}
}
public class ProductB_2:ProductTypeB
{
public override void UseProductB()
{
Debug.Log ("Use product B2.");
}
}

public abstract class AbstractFactory
{
public abstract ProductTypeA createProductA();
public abstract ProductTypeB createProductB();
}

public class BeijingFactory:AbstractFactory
{
public override ProductTypeA createProductA()
{
return new ProductA_1 ();
}
public override ProductTypeB createProductB ()
{
return new ProductB_1 ();
}
}
public class ShanghaiFactory:AbstractFactory
{
public override ProductTypeA createProductA()
{
return new ProductA_2 ();
}
public override ProductTypeB createProductB ()
{
return new ProductB_2 ();
}
}
////--------------------------------------------------------------------
// Debug.Log ("Test Abstract Factory:");
// AbstractFactory beijingchang = new BeijingFactory ();
// AbstractFactory shanghaichang = new ShanghaiFactory ();
// ProductTypeA beijingA = beijingchang.createProductA ();
// beijingA.UseProductA ();
// ProductTypeB shanghaiB = shanghaichang.createProductB ();
// shanghaiB.UseProductB ();

}

Singleton

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
namespace CsharpDesignPattern.Singleton
{
/// <summary>
/// 解决:单例,任务管理器等,文件操作等。
/// 案例:所以有两点,1 只能有一个实例 2 提供一个全局访问节点
/// 1 私有的构造函数--外部不能通过new创建新的实例
/// 2 私有静态变量--对线程只能有一个实例
/// 3 公开的静态访问方法
/// </summary>
public class Singleton
{
private static Singleton _theInstance;
private Singleton()
{

}
public static Singleton GetInstance()
{
if (_theInstance == null)
{
_theInstance = new Singleton ();
}
return _theInstance;
}
}

public class SingletonThread
{
private static SingletonThread _theInstance;
private static readonly object locker = new object();// new added
private SingletonThread()
{

}

public static SingletonThread GetInstance()
{
// 当第一个线程运行到这里时,此时会对locker对象 "加锁",
// 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
// lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
lock (locker)
{
// 如果类的实例不存在则创建,否则直接返回
if (_theInstance == null)
{
_theInstance = new SingletonThread();
}
}
return _theInstance;
}
}
}

Adapter

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
namespace CsharpDesignPattern.Adapter
{
/// <summary> 类的适配器
/// 解决:复用现有的一些类
/// 案例:如二插头转三插头,我们已经有两个孔插头的电器了,目标是要适配三个孔的插座。我们构造一个转换头。
/// 1 我们现有的类,有两个孔插头(适配者,Adaptee),方法SpecialRequest
/// 2 客户希望调用三个孔(适配器,Adapter),方法Request,用接口实现
/// 3 适配器类实现,三个孔的Interface,继承两个孔类。相当于是个外壳。
/// </summary>

public interface ThreeHole
{
void Request();
}

public abstract class TwoHole //其实没必要是抽象的类吧???
{
public void SpecialRequest()
{
Debug.Log ("This is two hole method.");
}
}

public class Adaptor:TwoHole,ThreeHole
{
public void Request()
{
this.SpecialRequest ();//this or base???
}
}

/// <summary>对象适配器
/// 1 实现客户的Threehole需求
/// 2 不能继承,但必须借用Twohole 的方法--利用对象
/// </summary>
public class TwoHole_obj
{
public void SpecialRequest()
{
Debug.Log ("This is two hole method...obj");
}
}
public class ThreeHole_obj
{
public virtual void Request()
{
}
}

public class Adaptor_obj:ThreeHole_obj
{
public TwoHole_obj mytwohole = new TwoHole_obj();
public override void Request()
{
mytwohole.SpecialRequest ();
}
}
////--------------------------------------------------------------------
// Debug.Log ("Test Adapter:");
// ThreeHole myhole = new Adaptor ();
// myhole.Request ();
//
// ThreeHole_obj mythreehole = new Adaptor_obj ();
// mythreehole.Request ();
}

Proxy

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
namespace CsharpDesignPattern.Proxy
{
/// <summary>
/// 代理模式主要用在:虚拟代理、远程代理、智能引用代理、保护代理等
/// 解决:一个客户不想或者不能直接访问某个对象。如远程桌面。
/// 案例:代购
/// 1 抽象角色Person,代理者和被代理者的公共接口
/// 2 真实角色Real 真实对象
/// 3 代理角色Friend 含有对真实主题的引用,在需要的时候创建真实主题对象,从而操作真实主题对象;
/// 代理角色通常在将客户端调用传递到真实主题之前或之后,都要执行一些其他的操作,而不是单纯地将调用传递给真实主题对象。
/// </summary>

public abstract class Person
{
public abstract void BuySomething();
}
public class RealBuyer:Person
{
public override void BuySomething()
{
Debug.Log ("Someone real buy something...");
}
}

public class Friend:Person
{
RealBuyer TheBuyer;
public override void BuySomething()
{
if (TheBuyer == null)
{
TheBuyer = new RealBuyer ();
}
this.PreBuy ();
Debug.Log ("通过代理类访问真实实体对象的方法:");
TheBuyer.BuySomething ();
this.PostBuy ();
}
public void PreBuy()
{
Debug.Log ("Pre buying...");
}
public void PostBuy()
{
Debug.Log ("Post Buying...");
}
}
////--------------------------------------------------------------------
// Debug.Log ("Test Proxy:");
// Person myDaigou = new Friend ();
// myDaigou.BuySomething ();
}

Facade

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
namespace CsharpDesignPattern.Facade
{
/// <summary>
/// Design pattern.
/// </summary>
//https://www.cnblogs.com/JiYF/p/6484208.html

//外观模式:为子系统中一组接口提供一个一致的界面,即定义一个高层接口,增加子系统的易用性。
//外观模式完美体现了依赖倒转原则和迪米特法则。
//设计初期阶段,在MVC三层架构中,任意两层间建立外观Facade。
//子系统会因不断演化变得复杂,增加外观Facade提供简单简单接口减少依赖。
//在维护一个大的遗留系统时,新的开发又必须依赖其部分功能。此时,开发一个外观Facade类,从老系统中抽象出比较清晰的简单接口。让新系统只与Facade交互,而Facade与遗留代码交互所有的工作。

//解决:系统和子系统:不同的power and off 命令
//1 Facade负责子系统的封装调用
//2 负责具体的子系统 subsystem

public class Subsystem1
{
public void power1()
{
Debug.Log ("power 1...");
}
public void poweroff1()
{
Debug.Log ("power off 1...");
}
}
public class Subsystem2
{
public void power2()
{
Debug.Log ("power 2 ...");
}
public void poweroff2()
{
Debug.Log ("power off 2...");
}
}

public class Facade
{
private Subsystem1 subsys1;
private Subsystem2 subsys2;

public Facade()
{
subsys1 = new Subsystem1 ();
subsys2 = new Subsystem2 ();
}

public void power()
{
subsys1.power1 ();
subsys2.power2 ();
}
public void poweroff()
{
subsys1.poweroff1 ();
subsys2.poweroff2 ();
}
}
////--------------------------------------------------------------------
// Debug.Log ("Test Facade:");
// Facade myfacade = new Facade ();
// myfacade.power ();
// myfacade.poweroff ();
}

Mediator

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
76
77
78
79
80
81
82
83
84
85
namespace CsharpDesignPattern.Mediator
{
/// <summary>
/// 解决:各种中间平台,比如QQ、游戏平台
/// 案例:聊天室
/// 1 聊天室管理:注册成员Register,处理消息Operation
/// 2 聊天的成员:设置中介SetRoom,发送消息Send,接收消息Receive
/// </summary>
public abstract class AbsMember
{
public abstract void SetRoom(ChatRoom room,string name);
public abstract void Send(Member to,string msg);
public abstract void Receive(string msg);
}

public abstract class AbsChatRoom
{
public abstract void Register(Member a);
public abstract void Operation(Member a,string b);
}

public class ChatRoom:AbsChatRoom
{
private List<Member> chatgroup;
public ChatRoom()
{
chatgroup = new List<Member>();
}
public override void Register(Member reg)
{
if(!chatgroup.Contains(reg))
{
chatgroup.Add (reg);
}
}
public override void Operation(Member toWho,string message)
{
if (!chatgroup.Contains (toWho)) {
Debug.Log ("There is no people you want to send message to...");
return;
}
else
{
toWho.Receive(message);
}
}
}

public class Member:AbsMember
{
private ChatRoom _Room;
private string _Name;
public override void SetRoom(ChatRoom room,string name)
{
this._Room = room;
this._Name = name;
}
public override void Send(Member to,string sendmessage)
{
if (_Room == null) {
Debug.Log ("Register the room first");
return;
}
else
{
_Room.Operation (to,sendmessage);
}
}
public override void Receive(string recmessage)
{
Debug.Log ("Receive : " + recmessage);
}
}
////--------------------------------------------------------------------
// Debug.Log ("Test Mediator:");
// ChatRoom TheRoom = new ChatRoom ();
// Member a = new Member ();
// Member b = new Member ();
// TheRoom.Register (a);
// TheRoom.Register (b);
// a.SetRoom (TheRoom,"A");
// b.SetRoom (TheRoom,"B");
// a.Send (b,"Hi I am A...");
// b.Send (a,"Hey I am B...");
}

Observer

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
76
77
78
79
80
81
82
83
84
85
namespace CsharpDesignPattern.Observer
{
/// <summary>
/// 解决:
/// 1 解决一个对象状态发生改变,很多对象跟着更新。
/// 2 观察者和被观察者,实际上衍生出来的是订阅者和订阅号,参考微信公众号;或者MVC架构,也是典型的观察者设计模式;
/// 3 一般的使用delegate委托、事件来实现
/// 案例:
/// 1 订阅号 Subject(Tenxun)
/// 2 订阅者 Subscriber
/// </summary>

// 订阅号抽象类
public abstract class TenXun
{
// 保存订阅者列表
private List<IObserver> observers = new List<IObserver>();

public string Symbol { get; set; }
public string Info { get; set; }
public TenXun(string symbol, string info)
{
this.Symbol = symbol;
this.Info = info;
}

#region 新增对订阅号列表的维护操作
public void AddObserver(IObserver ob)
{
observers.Add(ob);
}
public void RemoveObserver(IObserver ob)
{
observers.Remove(ob);
}
#endregion

public void Update()
{
// 遍历订阅者列表进行通知
foreach (IObserver ob in observers)
{
if (ob != null)
{
ob.ReceiveAndPrint(this);
}
}
}
}

// 具体订阅号类
public class TenXunGame : TenXun
{
public TenXunGame(string symbol, string info) : base(symbol, info)
{
}
}

// 订阅者接口
public interface IObserver
{
void ReceiveAndPrint(TenXun tenxun);
}

// 具体的订阅者类
public class Subscriber : IObserver
{
public string Name { get; set; }
public Subscriber(string name)
{
this.Name = name;
}

public void ReceiveAndPrint(TenXun tenxun)
{
Debug.Log(Name + tenxun.Symbol + tenxun.Info);
}
}
////--------------------------------------------------------------------
// Debug.Log ("Test Observer:");
// TenXun tenXun = new TenXunGame("TenXun Game", "Have a new game published ....");
// tenXun.AddObserver(new Subscriber("Learning Hard"));
// tenXun.AddObserver(new Subscriber("Tom"));
// tenXun.Update();
}

Strategy

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
namespace CsharpDesignPattern.Strategy
{
/// <summary>
/// 解决:干同一件事,需要实现不同的算法策略
/// 案例:计算个税/各种搜索,按名字、刚体等等
/// 1 接口,税计算Itax
/// 2 上下文,策略的设置、分配制者
/// 3 具体的策略计算PersonTax/EnterTax,都继承自Itax
/// </summary>

public interface Itax
{
double GetTax(double money);
}
public class PersonTax:Itax
{
public double GetTax(double money)
{
Debug.Log("Person Method called ...");
return money * 2;
}
}
public class EnterTax:Itax
{
public double GetTax(double money)
{
Debug.Log("Enterprise Method called ...");
return money * 3;
}
}

public class Context
{
private Itax _Strategy;
public Context(Itax taxstrategy)
{
Debug.Log ("Set the strategy...");
this._Strategy = taxstrategy;
}
public double GetResult(double money)
{
return _Strategy.GetTax (money);
}
}

//或者可以实现成静态类:
public class NewContext
{
public static double NewGetResult(double money,Itax taxer)
{
Debug.Log ("This is the static method...");
return taxer.GetTax (money);
}
}

////--------------------------------------------------------------------
// Debug.Log ("Test Strategy: ");
// Context mycontext;
// mycontext = new Context (new PersonTax());
// Debug.Log( mycontext.GetResult (20));
// mycontext = new Context (new EnterTax());
// Debug.Log( mycontext.GetResult (20));
//
// //静态调用
// NewContext.NewGetResult (30,new PersonTax());
}