public class commandfactory
{
public static command make( namevaluecollection parms )
{
string requestparm = parms["requestparm"];
command command = null;
//根据输入参数得到不同的command对象
switch ( requestparm )
{
case "1" :
command = new firstportal();
break;
case "2" :
command = new secondportal();
break;
default :
command = new firstportal();
break;
}
return command;
}
}
public interface command
{
void execute( httpcontext context );
}
public abstract class redirectcommand : command
{
//获得web.config中定义的key和url键值对,urlmap类详见下载包中的代码
private urlmap map = urlmap.soleinstance;
protected abstract void onexecute( httpcontext context );
public void execute( httpcontext context )
{
onexecute( context );
//根据key和url键值对提交到具体处理的页面
string url = string.format( "{0}?{1}", map.map[ context.request.url.absolutepath ], context.request.url.query );
context.server.transfer( url );
}
}
public class firstportal : redirectcommand
{
protected override void onexecute( httpcontext context )
{
//在输入参数中加入项portalid以便页面处理
context.items["portalid"] = "1";
}
}
public class secondportal : redirectcommand
{
protected override void onexecute(httpcontext context)
{
context.items["portalid"] = "2";
}
}
最后在actwebform.aspx.cs中:
datagrid.datasource = getsubjectdatasource( httpcontext.current.items["portalid"].tostring() );
datagrid.databind();
上面的例子展示了如何通过front controller集中和处理所有的请求,它使用commandfactory来确定要执行的具体操作,无论执行什么方法和对象,handler只调用command对象的execute方法,您可以在不修改 handler的情况下添加额外的命令。它允许让用户看不到实际的页面,当用户输入一个url时,然后系统将根据web.config文件将它映射到特定的url,这可以让程序员有更大的灵活性,还可以获得page controller实现中所没有的一个间接操作层。
对于相当复杂的web应用我们才会采用front controller模式,它通常需要将页面内置的controller替换为自定义的handler,在front controllrer模式下我们甚至可以不需要页面,不过由于它本身实现比较复杂,可能会给业务逻辑的实现带来一些困扰。
以上两个controller模式都是处理比较复杂的webform应用,相对于直接处理用户输入的应用来讲复杂度大大提高,性能也必然有所降低,为此我们最后来看一个可以大幅度提高程序性能的模式:page cache模式。
page cache模式下的webform
几乎所有的webform面临的都是访问很频繁,改动却很少的应用,对webform的访问者来说有相当多的内容是重复的,因此我们可以试着把webform或者某些相同的内容保存在服务器内存中一段时间以加快程序的响应速度。
这个模式实现起来很简单,只需在页面上加入:
<%@ outputcache duration="60" varybyparam="none" %>,
这表示该页面会在60秒以后过期,也就是说在这60秒以内所有的来访者看到该页面的内容都是一样的,但是响应速度大大提高,就象静态的html页面一样。
也许您只是想保存部分的内容而不是想保存整个页面,那么我们回到mvc模式中的sqlhelper.cs,我对它进行了少许修改:
public static dataset getportal()
{
dataset dataset;
if ( httpcontext.current.cache["select_portal_cache"] != null )
{
//如果数据存在于缓存中则直接取出
dataset = ( dataset ) httpcontext.current.cache["select_portal_cache"];
}
else
{
//否则从数据库中取出并插入到缓存中,设定绝对过期时间为3分钟
dataset = getdataset( sql_select_portal );
httpcontext.current.cache.insert( "select_portal_cache", dataset, null, datetime.now.addminutes( 3 ), timespan.zero );
}
return dataset;
}
在这里把select_portal_cache作为cache的键,把getdataset( sql_select_portal )取出的内容作为cache的值。这样除了程序第1次调用时会进行数据库操作外,在cache过期时间内都不会进行数据库操作,同样大大提高了程序的响应能力。
小结
自从.net框架引入设计模式以后在很大程度上提高了其在企业级应用方面的实力,可以毫不夸张的说在企业级应用方面.net已经赶上了java的步伐并大有后来居上之势,本文通过一个实例的讲解向读者展示了在.net框架下实现web设计模式所需的一些基本知识,希望能起到一点抛砖引玉的作用。
参考资源
下载地址
作者信息
袁剑
microsoft asp.net mvp
2003年12月6日