自从有了html与http,就有了浏览器与Web服务器,并有了Web应用,最初的交互模式是这样的:

该模式很好地运行了很多年。然而,随着计算机应用的发展,人们越来越不满足于只有静态内容的页面,而由某种机制动态产生html等代码的需求越来越迫切,于是,很多技术就应运而生,ASP.NET就是这样一种技术。从本质上讲,ASP.NET就是一种服务器端动态产生html、css、javascript等浏览器认识的代码的技术。ASP.NET的交互模式如下:

由该图可知,ASP.NET必须解决两大问题,一是如何与Web服务器(一般就是指IIS)进行交互,二是如何根据不同请求产生不同的html等代码。
***个问题,根据IIS版本(5.*,6.0,7.0)的不同,ASP.NET具有不同的进程模式与不同的交互模式,该问题不是本篇要讲述的。一般来说,大家不必关心该问题,而且要了解该问题,又必须清楚IIS各个版本的模型,而各个版本又各有各的不同,因此,我基本不准备讲述这个问题,大家有兴趣的话,可以自行搜索相关资料。
我们来讨论第二个问题,这里首先要说明的是,因为IIS7.0进程模式的变化比较大,我也没去了解IIS7.0的模型,因此,以下讲述及以后讲述将只针对IIS5.*与IIS6.0。我们有理由认为,针对IIS5.*与IIS6.0的讲述一般同样适用于IIS7.0。
先且按下该问题不表,我们来看一段请求玉帝把大象放到冰箱里的代码(为什么不是上帝?因为我中华不归上帝管),请大家先跟着我的思路来,别急,别急。
using System;
namespace ConsoleApplication3
11_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_45_2811_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_45_2811_Closed_Text').style.display='inline';" src="/files/uploadimg/20090423/1047402.gif" align=top>{
class Program
{
static void Main(string[] args)
{
Emperor emperor = new Emperor();
while (true)
{
Console.WriteLine("首先给玉帝准备好大象和冰箱。");
Console.WriteLine("输入大象的名字:");
string elephantName = Console.ReadLine();
Console.WriteLine("输入大象的体重:");
int elephantWeight = int.Parse(Console.ReadLine());
Console.WriteLine("输入冰箱的名字:");
string refrigeratorName = Console.ReadLine();
Elephant elephant = new Elephant()
{
Name = elephantName,
Weight = elephantWeight
};
Refrigerator refrigerator = new Refrigerator()
{
Name = refrigeratorName
};
Context context = new Context()
{
Elephant = elephant,
Refrigerator = refrigerator
};
emperor.ProcessRequest(context);
Console.WriteLine("是否要玉帝继续把大象关进冰箱里?");
string answer = Console.ReadLine();
if (answer == "n")
break;
}
}
}
class Emperor
{
public void ProcessRequest(Context context)
{
Elephant elephant = context.Elephant;
Refrigerator refrigerator = context.Refrigerator;
//***步,打开冰箱门
refrigerator.IsOpen = true;
string Console.WriteLine(.Format("玉帝打开了 {0} 的冰箱门。", refrigerator.Name));
//第二步,把大象放进去
refrigerator.Content = elephant;
string Console.WriteLine(.Format("玉帝把大象 {0} 放到冰箱 {1} 里了。", elephant.Name, refrigerator.Name));
//第三步,关上冰箱门
refrigerator.IsOpen = false;
string Console.WriteLine(.Format("玉帝关上了 {0} 的冰箱门。", refrigerator.Name));
}
}
class
Elephant
{
public string Name { get; set; }
public int Weight{ get; set; }
}
class
Refrigerator
{
public string Name { get; set; }
public bool IsOpen { get; set; }
private
object m_Content;
public object Content
{
get { return this.m_Content; }
set
{
if (!this.IsOpen)
throw new InvalidOperationException("冰箱门未打开,无法放进东西。");
if (this.m_Content != null)
throw new InvalidOperationException("冰箱内有东西,无法放进新的东西。");
this
.m_Content = value;
}
}
}
class
Context
{
public Elephant Elephant { get; set; }
public Refrigerator Refrigerator { get; set; }
}
}
- 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.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 1.
请大家先认真读懂该代码,该代码不会有问题吧,如果有问题,那么还请你一定先读懂该代码再往下看。
后来,玉帝累了,他想啊,我堂堂玉帝,居然亲自干这种没含量的活,但是顾客是玉帝的玉帝,又不能不干。于是,玉帝找了两个手下(把门大神、神象星宿)来帮他干活。
_Text_112146').style.display='none'; document.getElementById('Code_Open_Image_112146').style.display='inline'; document.getElementById('Code_Open_Text_112146').style.display='inline';" height=16 src="/files/uploadimg/20090423/1047403.gif" width=11 align=top>Code2
using System;
using System.Collections.Generic;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Emperor emperor = new Emperor();
while emperor.Init();
(true)
{
Console.WriteLine("首先给玉帝准备好大象和冰箱。");
Console.WriteLine("输入大象的名字:");
string elephantName = Console.ReadLine();
Console.WriteLine("输入大象的体重:");
int elephantWeight = int.Parse(Console.ReadLine());
Console.WriteLine("输入冰箱的名字:");
string refrigeratorName = Console.ReadLine();
Elephant elephant = new Elephant()
{
Name = elephantName,
Weight = elephantWeight
};
Refrigerator refrigerator = new Refrigerator()
{
Name = refrigeratorName
};
Context context = new Context()
{
Elephant = elephant,
Refrigerator = refrigerator
};
emperor.ProcessRequest(context);
Console.WriteLine("是否要玉帝继续把大象关进冰箱里?");
string answer = Console.ReadLine();
if (answer == "n")
break ;
}
}
}
class
Emperor
{
private IList<IEmperorModule> m_Modules;
public Context Context { get; set; }
public
void Init()
{
m_Modules = new List<IEmperorModule>();
new m_Modules.Add( OpenCloseRefrigeratorDoorModule());
new m_Modules.Add( PutElephantToRefrigeratorModule());
foreach
(IEmperorModule module in this.m_Modules)
{
this module.Init();
}
}
public
void ProcessRequest(Context context)
{
this .Context = context;
this
.OnOpenRefrigeratorDoor();
this .OnPutElephantToRefrigerator();
this .OnCloseRefrigeratorDoor();
}
public
event EventHandler OpenRefrigeratorDoor;
public event EventHandler PutElephantToRefrigerator;
public event EventHandler CloseRefrigeratorDoor;
protected
virtual void OnOpenRefrigeratorDoor()
{
EventHandler handler = this.OpenRefrigeratorDoor;
if (handler != null)
{
this handler(, EventArgs.Empty);
}
}
protected
virtual void OnPutElephantToRefrigerator()
{
EventHandler handler = this.PutElephantToRefrigerator;
if (handler != null)
{
this handler(, EventArgs.Empty);
}
}
protected
virtual void OnCloseRefrigeratorDoor()
{
EventHandler handler = this.CloseRefrigeratorDoor;
if (handler != null)
{
this handler(, EventArgs.Empty);
}
}
}
class
Elephant
{
public string Name { get; set; }
public int Weight{ get; set; }
}
class
Refrigerator
{
public string Name { get; set; }
public bool IsOpen { get; set; }
private
object m_Content;
public object Content
{
get { return this.m_Content; }
set
{
if (!this.IsOpen)
throw new InvalidOperationException("冰箱门未打开,无法放进东西。");
if (this.m_Content != null)
throw new InvalidOperationException("冰箱内有东西,无法放进新的东西。");
this
.m_Content = value;
}
}
}
class
Context
{
public Elephant Elephant { get; set; }
public Refrigerator Refrigerator { get; set; }
}
interface
IEmperorModule
{
void Init(Emperor emperor);
}
class
OpenCloseRefrigeratorDoorModule : IEmperorModule
{
IEmperorModule 成员#region IEmperorModule 成员
public void Init(Emperor emperor)
{
emperor.OpenRefrigeratorDoor += new EventHandler(this.OpenDoor);
emperor.CloseRefrigeratorDoor += new EventHandler(this.CloseDoor);
}
#endregion
private
void OpenDoor(object sender, EventArgs e)
{
Emperor emperor = (Emperor)sender;
Refrigerator refrigerator = emperor.Context.Refrigerator;
refrigerator.IsOpen = true;
string Console.WriteLine(.Format("玉帝的把门大神打开了 {0} 的冰箱门。", refrigerator.Name));
}
private
void CloseDoor(object sender, EventArgs e)
{
Emperor emperor = (Emperor)sender;
Refrigerator refrigerator = emperor.Context.Refrigerator;
refrigerator.IsOpen = false;
string Console.WriteLine(.Format("玉帝的把门大神关上了 {0} 的冰箱门。", refrigerator.Name));
}
}
class
PutElephantToRefrigeratorModule : IEmperorModule
{
IEmperorModule 成员#region IEmperorModule 成员
public void Init(Emperor emperor)
{
emperor.PutElephantToRefrigerator += new EventHandler(this.PutElephantToRefrigerator);
}
#endregion
private
void PutElephantToRefrigerator(object sender, EventArgs e)
{
Emperor emperor = (Emperor)sender;
Elephant elephant = emperor.Context.Elephant;
Refrigerator refrigerator = emperor.Context.Refrigerator;
refrigerator.Content = elephant;
string Console.WriteLine(.Format("玉帝的神象星宿把大象 {0} 放到冰箱 {1} 里了。", elephant.Name, refrigerator.Name));
}
}
}
- 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.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
观测该代码有哪些变化?玉帝增加了一个Init方法,该方法召集了那些干活的手下,并交待手下你们要干的事情(初始化)。所有手下都继承自IEmperorModule接口,该接口有一个Init方法,以初始化该手下能干的活。玉帝的ProcessRequest方法不再亲自干活了,而仅仅是在那边喊,该开门了,该把大象放进去了,该关门了。
来点题外话,上面代码应用了模板方法模式,或者说是模板方法的变种。什么,不是,没有抽象类,没有抽象方法,没有子类?请问,模板方法一定要有抽象类吗?一定要有抽象方法吗?一定要有子类吗?我想,模板方法的精髓,在于它规定了特定的步骤算法,而这些步骤在必要的时候可以委托给其它方法实现。在传统的模板方法中,是委托给子类实现,而在我们拥有委托的情况下,难道我们不能委托给其它类实现吗?其实,我想,学习设计模式,不要拘泥于形式,而要掌握其精髓,并灵活运用。就Gof的23种设计模式来说,我觉得其精髓几乎全部可由一句话概括。)
天有不测风云,人有旦夕祸福,某一天,这神象星宿病了,他赶不动超过1000斤的大象了,怎么办?玉帝于是又召集了超级神象星宿,可但凡有点能耐的都有点脾气,超级神象星宿表示,只有其它人赶不动的大象他才来赶。
Code3
using System;
using System.Collections.Generic;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Emperor emperor = new Emperor();
while emperor.Init();
(true)
{
Console.WriteLine("首先给玉帝准备好大象和冰箱。");
Console.WriteLine("输入大象的名字:");
string elephantName = Console.ReadLine();
Console.WriteLine("输入大象的体重:");
int elephantWeight = int.Parse(Console.ReadLine());
Console.WriteLine("输入冰箱的名字:");
string refrigeratorName = Console.ReadLine();
Elephant elephant = new Elephant()
{
Name = elephantName,
Weight = elephantWeight
};
Refrigerator refrigerator = new Refrigerator()
{
Name = refrigeratorName
};
Context context = new Context()
{
Elephant = elephant,
Refrigerator = refrigerator
};
emperor.ProcessRequest(context);
Console.WriteLine("是否要玉帝继续把大象关进冰箱里?");
string answer = Console.ReadLine();
if (answer == "n")
break ;
}
}
}
class
Emperor
{
private IList<IEmperorModule> m_Modules;
public Context Context { get; set; }
public
void Init()
{
m_Modules = new List<IEmperorModule>();
new m_Modules.Add( OpenCloseRefrigeratorDoorModule());
new m_Modules.Add( PutElephantToRefrigeratorModule());
new m_Modules.Add( SuperPutElephantToRefrigeratorModule());
foreach
(IEmperorModule module in this.m_Modules)
{
this module.Init();
}
}
public
void ProcessRequest(Context context)
{
this .Context = context;
this
.OnOpenRefrigeratorDoor();
this .OnPutElephantToRefrigerator();
this .OnCloseRefrigeratorDoor();
}
public
event EventHandler OpenRefrigeratorDoor;
public event EventHandler PutElephantToRefrigerator;
public event EventHandler CloseRefrigeratorDoor;
protected
virtual void OnOpenRefrigeratorDoor()
{
EventHandler handler = this.OpenRefrigeratorDoor;
if (handler != null)
{
this handler(, EventArgs.Empty);
}
}
protected
virtual void OnPutElephantToRefrigerator()
{
EventHandler handler = this.PutElephantToRefrigerator;
if (handler != null)
{
this handler(, EventArgs.Empty);
}
}
protected
virtual void OnCloseRefrigeratorDoor()
{
EventHandler handler = this.CloseRefrigeratorDoor;
if (handler != null)
{
this handler(, EventArgs.Empty);
}
}
}
class
Elephant
{
public string Name { get; set; }
public int Weight{ get; set; }
}
class
Refrigerator
{
public string Name { get; set; }
public bool IsOpen { get; set; }
private
object m_Content;
public object Content
{
get { return this.m_Content; }
set
Id('Codehighlighter1_3485_3771_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_3485_3771_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_3485_3771_Open_Text').style.display='inline';" src="/files/uploadimg/20090423/1047407.gif" align=top> {
if (!this.IsOpen)
throw new InvalidOperationException("冰箱门未打开,无法放进东西。");
if (this.m_Content != null)
throw new InvalidOperationException("冰箱内有东西,无法放进新的东西。");
this
.m_Content = value;
}
}
}
class
Context
{
public Elephant Elephant { get; set; }
public Refrigerator Refrigerator { get; set; }
private
IDictionary<string, object> m_Items;
public IDictionary<string, object> Items
{
get
none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"> {
if (this.m_Items == null)
this .m_Items = new Dictionary<string, object>();
return this.m_Items;
}
}
}
interface
IEmperorModule
{
void Init(Emperor emperor);
}
class
OpenCloseRefrigeratorDoorModule : IEmperorModule
{
IEmperorModule 成员#region IEmperorModule 成员
public void Init(Emperor emperor)
{
emperor.OpenRefrigeratorDoor += new EventHandler(this.OpenDoor);
emperor.CloseRefrigeratorDoor += new EventHandler(this.CloseDoor);
}
#endregion
private
void OpenDoor(object sender, EventArgs e)
{
Emperor emperor = (Emperor)sender;
Refrigerator refrigerator = emperor.Context.Refrigerator;
refrigerator.IsOpen = true;
string Console.WriteLine(.Format("玉帝的把门大神打开了 {0} 的冰箱门。", refrigerator.Name));
}
private
void CloseDoor(object sender, EventArgs e)
{
Emperor emperor = (Emperor)sender;
Refrigerator refrigerator = emperor.Context.Refrigerator;
refrigerator.IsOpen = false;
string Console.WriteLine(.Format("玉帝的把门大神关上了 {0} 的冰箱门。", refrigerator.Name));
}
}
class
PutElephantToRefrigeratorModule : IEmperorModule
{
IEmperorModule 成员#region IEmperorModule 成员
public void Init(Emperor emperor)
{
emperor.PutElephantToRefrigerator += new EventHandler(this.PutElephantToRefrigerator);
}
#endregion
private
void PutElephantToRefrigerator(object sender, EventArgs e)
{
Emperor emperor = (Emperor)sender;
Elephant elephant = emperor.Context.Elephant;
Refrigerator refrigerator = emperor.Context.Refrigerator;
if
(elephant.Weight > 1000)
{
Console.WriteLine("这头大象实在太重了,我神象星宿挪不动阿。");
}
else
{
refrigerator.Content = elephant;
emperor.Context.Items["HasPutElephant"] = true;
string Console.WriteLine(.Format("玉帝的神象星宿把大象 {0} 放到冰箱 {1} 里了。", elephant.Name, refrigerator.Name));
}
}
}
class
SuperPutElephantToRefrigeratorModule : IEmperorModule
{
IEmperorModule 成员#region IEmperorModule 成员
public void Init(Emperor emperor)
{
emperor.PutElephantToRefrigerator += new EventHandler(this.PutElephantToRefrigerator);
}
#endregion
private
void PutElephantToRefrigerator(object sender, EventArgs e)
{
Emperor emperor = (Emperor)sender;
Elephant elephant = emperor.Context.Elephant;
Refrigerator refrigerator = emperor.Context.Refrigerator;
object
hasPutElephant;
if (emperor.Context.Items.TryGetValue("HasPutElephant", out hasPutElephant))
{
if (hasPutElephant is bool && ((bool)hasPutElephant) == true)
{
Console.WriteLine("已经有人把大象放进冰箱了,我超级神象星宿就歇歇了。");
return ;
}
}
refrigerator.Content = elephant;
emperor.Context.Items["HasPutElephant"] = true;
string Console.WriteLine(.Format("玉帝的超级神象星宿把大象 {0} 放到冰箱 {1} 里了。", elephant.Name, refrigerator.Name));
}
}
}- 1.
- 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.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
仔细琢磨该代码,请问你发现了什么?如果你发现的是灵活的可扩展性和可配置性,以及各手下之间的交互,那么恭喜你,你悟性很高。如果你还发现了职责链模式,那么恭喜你,你悟性非常高。(该代码中两个神象星宿的交互完全可以通过在Context中增加一个bool值属性来实现,之所有这里用Items字典,是为了演示如果你不具有修改Context的源代码的时候,该如何处理。)
好了,ASP.NET的设计思想讲完了。什么,还没开始?你没发现我们的Program就是HttpRuntime、Emperor就是HttpApplication、Context就是HttpContext、IEmperorModule就是IHttpModule吗?什么,没发现?那么,让我们来看看ASP.NET的源代码吧。(本想把整个方法的源代码都贴上来,但是显得过于冗长,因此删掉非关键代码,并以//……省略……代替。)
如此,你明白了吗?
【编辑推荐】