柔情似水 发表于 2015-1-18 11:30:52

ASP.NET教程之切磋与对照Java和.NET的事务处置框架仓酷云

学习asp.net两个月有余了,除了对html、web控件比较熟悉(应该是说都能理解和接受)之外,竟不知道自己还会什么。看了两本书:《精通asp.net网络编程》(人民邮电出版社)、《asp.net实用案例教程》(清华大学出版社)。 事务驱动模子

  事务驱动模子是软件体系平台中的一个主要地区,古代软件体系大批地利用事务驱动的处置办法,特别在用户界面方面。固然云云,已往在软件开辟言语中一向没有融进事务处置的因子,直到.net的呈现,才将事务处置的事情负荷一部分的分拨给编译器,从而略微加重开辟者的包袱。

  下图显现事务模子的构成分子:



<br>
  Subscriber需事前和publisher预订要承受其公布的某事务(下图a1),publisher在某事务产生今后,必须师长教师成该事务的相干数据对象(下图a2.1),然后经由过程办法挪用来关照subscriber(下图a2.2),也就是用回调(callback)的体例来关照subscriber。固然在预订的时分,其实不必定要由subscriber本身来预订,也能够由另外一个对象来协助预订。其静态图形表示以下:



<br>
  本文其实不切磋异步的信息传送,也就是在全部事务的处置历程傍边,publisher和subscriber对象皆必要同时存在。假如关于离线(offline)的体例来处置事务有乐趣的话,请参阅Java的JMS(JavaMessageService)和.NET的LCE(LooselyCoupledEvents)。

  事务是甚么?

  那末,究竟事务是甚么?在软件体系中要怎样表达一个事务?一个事务应当包含两个工具:辨认事务的称号(eventidentity),和事务的相干的数据(eventdata)。比方,一个键盘按键被按下的事务大概叫KeyPressedEvent,事务数据则为该按键的代码。

  先条件到公布事务是用挪用办法的体例(回调),不外有一个成绩,就是publisher没法事前晓得subscriber的范例。在Java的编码形式傍边,回调可使用接口形式,也就是publisher必须事前界说好一个在公布事务中利用的接口,subscriber完成该接口中的办法,publisher则经由过程挪用接口中的办法来完成公布事务的事情。以下图:



<br>
  如许,在Java的编码形式中,一个事务的辨认称号就是接口称号和个中的办法称号,而事务数据则天然是接口办法的参数了。Java关于这个接口的定名作风为XXXListener,望文生义就是某事务的聆听者。比方:

publicinterfaceKeyListenerextendsEventListener{
 publicvoidkeyTyped(KeyEvente);
 publicvoidkeyPressed(KeyEvente);
 publicvoidkeyReleased(KeyEvente);
}
  因为一个接口中能够包括多个办法,以是Java在计划事务的时分,是将一组相干联的事务放在一同,如许计划的长处是能够很好的将事务做分类,而且在publisher中假如要处置的事务较多的话,可使用对照少的成员变量来纪录subscribers。弱点是假如subscriber只对事务接口中的部分事务有乐趣,也必须要通盘完成该接口(以是在AWT里有java.awt.event.XXXAdapter笼统帮助类)。另外一个弱点则是必须要为每类事务界说一个接口范例,即便大概年夜部分的事务只要少少的办法。

  微软在为C#言语定名的时分,就决心隐喻C#是从C/C++为基本开展而得的面向对象程序言语,鼻祖毫不是Java,以是一定要保存一些C/C++的言语机制。在C/C++内里对回调的计划体例就是用函数指针,想固然C#也但愿间接利用相似函数挪用的体例来做为事务公布的办法。以下图:



<br>
  以是C#希冀利用函数指针范例来作为事务的辨认称号,然后用函数的参数来传送事务数据。我们先用一段C++代码来刻画这幅丹青:

Eventtypedefinition:
//界说KeyPressedCallback为一个函数指针的范例,
//该函数承受一个整数型参数,无前往值
typedefvoid(*KeyPressedCallback)(intkeyCode);

Publisher:
classPublisher
{
 publicKeyPressedCallbackKeyPressedSink=null;
 ...
 voidFireEvent(intKeyCode)
 {
  if(KeyPressedSink!=null)
  (*KeyPressedSink)(keyCode);//callback
 }
}

Subscriber:
voidKeyPressedHandler(intkeyCode)
{
 ...
}
...
Publisherpublisher=newPublisher();
//reGISter
publisher.KeyPressedSink=&KeyPressedHandler;
  一个今世的纯面向对象程序言语,是一定但愿要把形成程序庞大和不容易保护的指针给往除的。以是在C#言语机制傍边,必将要制造新的元从来代替,因而delegate(托付)呈现了。以下:

Eventtypedefinition:

//界说KeyPressedDelegate为一个相似函数指针的范例,
//该函数承受一个整数型参数,无前往值
delegatevoidKeyPressedDelegate(intkeyCode);

Publisher:
classPublisher
{
 publicKeyPressedDelegateKeyPressed=null;
 ...
 voidFireEvent(intKeyCode)
 {
  if(KeyPressed!=null)
   KeyPressed(keyCode);
 }
}

Subscriber:
voidKeyPressedHandler(intkeyCode)
{
 ...
}
...
Publisherpublisher=newPublisher();
//register
publisher.KeyPressed=KeyPressedHandler;
  一入手下手,你能够把KeyPressedDelegate当做是与函数指针相相似的工具,经由过程它你能够援用一个实例办法或静态办法,就仿佛援用一个对象一样。然后能够经由过程这个delegate间接挪用其援用的办法。可是上面你会看到delegate更扩展了其援用才能。
事务的预订和公布

  Publisher必须可以承受多个subscribers的预订,以是在publisher傍边必须保护预订者的列表以供未来公布事务利用。在Java言语的形式中,并没有供应出格的工具来匡助这件事,能够本人用collection类来做,比方可使用ArrayList对象来做纪录。Java的预订办法名的作风为addXXXListener(),由于在publisher端必须把subscriber对象“增加”到预订者列表前面,以下图:



<br>
  关于subscriber来讲,预订举措的外部处置是黑箱的,subscriber不必体贴publisher是怎样做预订纪录的。参考以下代码片断:

classPublisher{
 privateArrayListlistenerList=newArrayList();
 publicvoidaddKeyListener(KeyListenerl){
  listenerList.add(l);
 }
 publicvoidfireKeyPressedEvent(intkeyCode){
  Iteratoriter=listenerList.iterator();
  while(iter.hasNext()){
   KeyListenerl=(KeyListener)iter.next();
   l.keyPressed(keyCode);
  }
 }
}
  固然这段代码只是复杂的表示,假如要思索多线程的平安成绩,大概要在addKeyListener()后面加上synchronized;另有,有预订就一定响应的有“退订”(removeXXXListener()),在这里就不再把它写出来。

  假如每一个publisher都要如许反复撰写如许的代码切实其实很贫苦。以是在.net中必将但愿可以供应一种用来匡助publisher纪录预订者,和公布事务的工具。按一样平常计划者的开端设法,必定是先供应一个帮助类来帮忙:



<br>
  从语法上思索简化,add/remove举措应当能够用C++的operator=()、operator+=()和operator-=()来完成。像如许:

Publisherpublisher=newPublisher();
...
publisher.KeyEventHandlerDelegate+=KeyPressedHandler;
//同等于
//publisher.EventHandlerDelegate.add(KeyPressedHandler);
  假如能够如许撰写的话,的确很复杂。不外在强迫性范例(strongly-typed)言语体系中,必须准确的界说add()办法参数中的delegate范例,如许仿佛没法写出一个能够公用的基本类。以是在.NET中,是分离delegate关头字,经由过程复杂的语法,借助编译器来帮我们主动天生相干的代码。因而把delegate的才能再予以增强了:

Eventtypedefinition:
publicdelegatevoidKeyPressedDelegate(intkeyCode);

Publisher:
classPublisher
{
 publicKeyPressedDelegateKeyPressed;
 ...
 voidFireKeyPressedEvent(intKeyCode)
 {
  if(KeyPressed!=null)
   //顺次挪用纪录在KeyPressed中的一切办法
   KeyPressed(keyCode);
 }
}

Subscriber:
voidOnKeyPressed(intkeyCode)
{
 ...
}
voidOnKeyPressed2(intkeyCode)
{
 ...
}
...
Publisherpublisher=newPublisher();
publisher.KeyPressed=OnKeyPressed;  //预订
publisher.KeyPressed+=OnKeyPressed2; //预订另外一个
  如许一个delegate不但能够协助纪录一个以上的subscribers,也能够复杂的经由过程一行的挪用语句来公布事务。实在编译器会为每个delegate天生一个响应的类来匡助处置这些事情,不外是作为一个只是编写使用体系的程序员是不用要往懂得这些细节的,有乐趣的人能够往研讨System.Delegate和System.MulticastDelegate类。

  下面看到的了局应当已是对照中意的,可是仍有改良空间。起首,由于一个delegate成员是public的,任何人都能够恣意的间接打仗,有掉面向对象天下中的信息封装和埋没(informationencapsulationandhiding)的准绳。以是在C#中又增添一个关头字“event”,用在放在声明一个delegate成员变量的后面,如许暗示只要在声明这个delegate的类外部才能够间接对它举行subscriber挪用。

publicdelegatevoidKeyPressedDelegate(intkeyCode);
classPublisher
{
 publiceventKeyPressedDelegateKeyPressed;
 ...
 voidFireKeyPressedEvent(intKeyCode)
 {
  if(KeyPressed!=null)
   //只要在Publisher才能够
   KeyPressed(keyCode);
 }
}

//outsideofPublisher...
Publisherpublisher=newPublisher();
//!!!不同意!!!会编译毛病!!!
publisher.KeyPressed(100);
  接着,eventdelegate是以一个成员变量的体例存在,假如能以属性的体例让外界举行存取,不是更好吗。因而又增添了eventAccessors。在C#言语中,是利用add和remove来封装实践的+=和-=操纵。以下:

classPublisher
{
 protectedeventKeyPressedDelegatem_KeyPressed;

 //eventaccessor。界说一个事务属性。
 publiceventKeyPressedDelegateKeyPressed
 {
  add
  {
   m_KeyPressed+=value;
  }
  remove
  {
   m_KeyPressed-=value;
  }
 }
 voidFireKeyPressedEvent(intKeyCode)
 {
  if(KeyPressed!=null)
  m_KeyPressed(keyCode);
 }
}
  不论是事务变量大概是事务属性,对声明事务变量和属性的类的内部,只能对它做+=和-=操纵。如许能够增强它的平安性。固然eventaccessor只要add和remove操纵,以是不论是任何人(包含声明该事务属性的类外部),也只能对事务属性做+=和-=操纵。
经由如许的改良,能够实际上更削弱publisher和subscriber之间的耦协力了。事务数据

  接上去我们谈一谈另外一个在事务模子中的主要脚色,就是在事务公布中被传送的“事务数据”。

  一个subscriber在承受统一种事务的时分,大概来自分歧的publisher,以是天然地但愿晓得收回事务的人是谁,也就是在传送的参数傍边,必须包括一个publisher对象的援用。在Java中,保举一切的事务数据类都承继java.util.EventObject类。由于在天生一个EventObject对象的时分,必须给一个eventsource对象作为参数。然后能够经由过程EventObject的getSource()办法来获得这个对象。在EventObject内里,并没有包括其他任何事务数据,以是假如在事务的传送历程傍边,有任何事务数据必要传送,就必须从EventObject派生出一个新的子类出来。以下图:



<br>
  在.net傍边也有一个类似的类叫System.EventArgs,可是这个类的内容是空的,以下:

publicclassEventArgs
{
 publicstaticreadonlyEventArgsEmpty;
 staticEventArgs()
 {
  Empty=newEventArgs();
 }
 publicEventArgs()
 {}
}
  .NET以为纷歧定一切的subscriber都对eventsource感乐趣,以是假如必要的话,就把eventsource当做是delegate办法的参数来传送好了。.NET界说了一个尺度的delegateEventHandler,以下是它的署名(signature):

publicdelegatevoidEventHandler(objectsender,EventArgse);
  今后,只需你必要的delegate的署名与EventHandler不异的话,就间接用它了。这里所谓的署名不异,是指参数的范例和前往值的范例皆不异。

  Java和.NET都但愿用户在界说的事务数据类的时分,尽量的利用保举的基类,由于如许在publisher对收回的事务数据内容有所变动或扩展的时分,对subscriber的打击会对照小,这是因为多型(polymorphism)机制的匡助。

  停止语

  经由这番剖析以后,应当可以对照分明的懂得到Java和.NET事务处置框架的计划思绪,但愿有助于读者更进一步了解其框架的构成历程。从言语的角度来看,.NET切实其实有一些针对性的改良和试图简化对事务的处置,Java则仍保有其一向繁复的作风。读者如有任何定见和指教,能够经由过程e-mail与我交换:bruceyou@sina100.com。计算机发展到这个时候,很多技术日益成熟,想学好一种技术都是不容易的,当你学会用的时候你对它的很多原理可能很不了解)

蒙在股里 发表于 2015-1-24 14:50:28

但是目前在CGI中使用的最为广泛的是Perl语言。所以,狭义上所指的CGI程序一般都是指Perl程序,一般CGI程序的后缀都是.pl或者.cgi。

变相怪杰 发表于 2015-1-24 20:10:41

当然我们在选择Asp.net主机是,除了要考虑服务提供商在版本是否是实时更新以外,机房的环境和配置也是非常重要的,通常选择骨干网的机房,在速度和稳定性上会非常有保证。

再现理想 发表于 2015-1-26 11:03:15

是指转换后的Servlet程序代码的行数。这给调试代码带来一定困难。所以,在排除错误时,可以采取分段排除的方法(在可能出错的代码前后输出一些字符串,用字符串是否被输出来确定代码段从哪里开始出错)。

活着的死人 发表于 2015-2-7 13:40:13

最强的技术支持WebService,而且有.NET的所有library做后盾。而且ASP.NET在.NET3.5中还有微软专门为AJAX开发的功能--ASP.NETAJAX。

深爱那片海 发表于 2015-2-22 02:49:30

现在主流的网站开发语言无外乎asp、php、asp.net、jsp等。

简单生活 发表于 2015-3-6 19:56:19

同时也感谢博客园给我们这个平台,也感谢博客园的编辑们做成专题引来这么多高人指点。

若相依 发表于 2015-3-7 10:20:11

最强的技术支持WebService,而且有.NET的所有library做后盾。而且ASP.NET在.NET3.5中还有微软专门为AJAX开发的功能--ASP.NETAJAX。

只想知道 发表于 2015-3-14 20:17:32

这也就是最近几年来随着各种新的后台技术的诞生,CGI应用在Internet上越来越少的原因。CGI方式不适合大访问量的应用。

爱飞 发表于 2015-3-21 14:00:51

碰到复杂点的问题都不知道能不能解决,现在有点实力的公司都选择自已在开源的基础上做开发。但没听说过有人在IIS上做改进的,windows、sqlserver集群方面的应用也很少见。

不帅 发表于 2015-3-31 04:33:38

现在主流的网站开发语言无外乎asp、php、asp.net、jsp等。

飘灵儿 发表于 2015-4-16 13:28:25

主流网站开发语言之JSP:JSP和Servlet要放在一起讲,是因为它们都是Sun公司的J2EE(Java2platformEnterpriseEdition)应用体系中的一部分。

精灵巫婆 发表于 2015-4-18 00:50:10

由于JSP/Servlet都是基于Java的,所以它们也有Java语言的最大优点——平台无关性,也就是所谓的“一次编写,随处运行(WORA–WriteOnce,RunAnywhere)”。除了这个优点,JSP/Servlet的效率以及安全性也是相当惊人的。

莫相离 发表于 2015-4-18 10:34:53

这也就是最近几年来随着各种新的后台技术的诞生,CGI应用在Internet上越来越少的原因。CGI方式不适合大访问量的应用。

分手快乐 发表于 2015-4-18 16:19:28

使用普通的文本编辑器编写,如记事本就可以完成。由脚本在服务器上而不是客户端运行,ASP所使用的脚本语言都在服务端上运行,用户端的浏览器不需要提供任何别的支持,这样大提高了用户与服务器之间的交互的速度。

小妖女 发表于 2015-4-19 16:22:54

在asp.net虚拟主机的服务提供商中,目前首推的是CNNIC的其中一家域名注册机构---时代互联(www.now.net.cn),他们早在2001年微软刚推出Asp.net时就推出了对应的Asp.net虚拟主机了,经笔者的使用测试,他提供的Asp.net性能非常的稳定,版本也会定期的更新,目前他的

冷月葬花魂 发表于 2015-4-27 19:51:58

虽然在形式上JSP和ASP或PHP看上去很相似——都可以被内嵌在HTML代码中。但是,它的执行方式和ASP或PHP完全不同。在JSP被执行的时候,JSP文件被JSP解释器(JSPParser)转换成Servlet代码,然后Servlet代码被Java编译器编译成.class字节文件,这样就由生成的Servlet来对客户端应答。所以,JSP可以看做是Servlet的脚本语言(ScriptLanguage)版。

老尸 发表于 2015-4-28 22:18:54

由于CGI程序每响应一个客户就会打开一个新的进程,所以,当有多个用户同时进行CGI请求的时候,服务器就会打开多个进程,这样就加重了服务器的负担,使服务器的执行效率变得越来越低下。

愤怒的大鸟 发表于 2015-5-1 00:11:22

ASP.net的速度是ASP不能比拟的。ASP.net是编译语言,所以,当第一次加载的时候,它会把所有的程序进行编译(其中包括worker进程,还有对语法进行编译,形成一个程序集),当程序编译后,执行速度几乎为0。
页: [1]
查看完整版本: ASP.NET教程之切磋与对照Java和.NET的事务处置框架仓酷云