当前位置: 首页 > news >正文

如何做网站专题全国十大跨境电商排名

如何做网站专题,全国十大跨境电商排名,专业做标书,苏州建设公司网站建设《解剖PetShop》系列之四 四 PetShop之ASP.NET缓存 如果对微型计算机硬件系统有足够的了解#xff0c;那么我们对于Cache这个名词一定是耳熟能详的。在CPU以及主板的芯片中#xff0c;都引入了这种名为高速缓冲存 储器#xff08;Cache#xff09;的技术。因为Cache的存取速…《解剖PetShop》系列之四 四 PetShop之ASP.NET缓存 如果对微型计算机硬件系统有足够的了解那么我们对于Cache这个名词一定是耳熟能详的。在CPU以及主板的芯片中都引入了这种名为高速缓冲存 储器Cache的技术。因为Cache的存取速度比内存快因而引入Cache能够有效的解决CPU与内存之间的速度不匹配问题。硬件系统可以利用 Cache存储CPU访问概率高的那些数据当CPU需要访问这些数据时可以直接从Cache中读取而不必访问存取速度相对较慢的内存从而提高了 CPU的工作效率。软件设计借鉴了硬件设计中引入缓存的机制以改善整个系统的性能尤其是对于一个数据库驱动的Web应用程序而言缓存的利用是不可或缺 的毕竟数据库查询可能是整个Web站点中调用最频繁但同时又是执行最缓慢的操作之一我们不能被它老迈的双腿拖缓我们前进的征程。缓存机制正是解决这 一缺陷的加速器。 4.1  ASP.NET缓存概述 作为.Net框架下开发Web应用程序的主打产品ASP.NET充分考虑了缓存机制。通过某种方法将系统需要的数据对象、Web页面存储在内存 中使得Web站点在需要获取这些数据时不需要经过繁琐的数据库连接、查询和复杂的逻辑运算就可以“触手可及”如“探囊取物”般容易而快速从而提 高整个Web系统的性能。 ASP.NET提供了两种基本的缓存机制来提供缓存功能。一种是应用程序缓存它允许开发者将程序生成的数据或报表业务对象放入缓存中。另外一种缓存机制是页输出缓存利用它可以直接获取存放在缓存中的页面而不需要经过繁杂的对该页面的再次处理。 应用程序缓存其实现原理说来平淡无奇仅仅是通过ASP.NET管理内存中的缓存空间。放入缓存中的应用程序数据对象以键/值对的方式存储这便于用户在访问缓存中的数据项时可以根据key值判断该项是否存在缓存中。 放入在缓存中的数据对象其生命周期是受到限制的即使在整个应用程序的生命周期里也不能保证该数据对象一直有效。ASP.NET可以对应用程序缓 存进行管理例如当数据项无效、过期或内存不足时移除它们。此外调用者还可以通过CacheItemRemovedCallback委托定义回调方法 使得数据项被移除时能够通知用户。 在.Net Framework中应用程序缓存通过System.Web.Caching.Cache类实现。它是一个密封类不能被继承。对于每一个应用程序域 都要创建一个Cache类的实例其生命周期与应用程序域的生命周期保持一致。我们可以利用Add或Insert方法将数据项添加到应用程序缓存中如 下所示Cache[First] First Item;Cache.Insert(Second, Second Item); 我们还可以为应用程序缓存添加依赖项使得依赖项发生更改时该数据项能够从缓存中移除string[] dependencies {Second};Cache.Insert(Third, Third Item,new System.Web.Caching.CacheDependency(null, dependencies)); 与之对应的是缓存中数据项的移除。前面提到ASP.NET可以自动管理缓存中项的移除但我们也可以通过代码编写的方式显式的移除相关的数据项Cache.Remove(First); 相对于应用程序缓存而言页输出缓存的应用更为广泛。它可以通过内存将处理后的ASP.NET页面存储起来当客户端再一次访问该页面时可以省去 页面处理的过程从而提高页面访问的性能以及Web服务器的吞吐量。例如在一个电子商务网站里用户需要经常查询商品信息这个过程会涉及到数据库访 问以及搜索条件的匹配在数据量较大的情况下如此的搜索过程是较为耗时的。此时利用页输出缓存就可以将第一次搜索得到的查询结果页存储在缓存中。当用 户第二次查询时就可以省去数据查询的过程减少页面的响应时间。 页输出缓存分为整页缓存和部分页缓存。我们可以通过OutputCache指令完成对Web页面的输出缓存。它主要包含两个参 数Duration和VaryByParam。Duration参数用于设置页面或控件进行缓存的时间其单位为秒。如下的设置表示缓存在60秒内有 效% OutputCache Duration“60“ VaryByParam“none“ % 只要没有超过Duration设置的期限值当用户访问相同的页面或控件时就可以直接在缓存中获取。使用VaryByParam参数可以根据设置的参数值建立不同的缓存。例如在一个输出天气预报结果的页面中如果需要为一个ID为txtCity的TextBox控件建立缓存其值将显示某城市的气温那么我们可以进行如下的设置% OutputCache Duration”60” VaryByParam”txtCity” % 如此一来ASP.NET会对txtCity控件的值进行判断只有输入的值与缓存值相同才从缓存中取出相应的值。这就有效地避免了因为值的不同而导致输出错误的数据。 利用缓存的机制对性能的提升非常明显。通过ACTApplication Center Test的测试可以发现设置缓存后执行的性能比未设置缓存时的性能足足提高三倍多。 引入缓存看来是提高性能的“完美”解决方案然而“金无足赤人无完人”缓存机制也有缺点那就是数据过期的问题。一旦应用程序数据或者页面结果 值发生的改变那么在缓存有效期范围内你所获得的结果将是过期的、不准确的数据。我们可以想一想股票系统利用缓存所带来的灾难当你利用错误过期的数据 去分析股市的风云变幻时你会发现获得的结果真可以说是“失之毫厘谬以千里”看似大好的局面就会像美丽的泡沫一样用针一戳转眼就消失得无影无踪。 那么我们是否应该为了追求高性能而不顾所谓“数据过期”所带来的隐患呢显然在类似于股票系统这种数据更新频繁的特定场景下数据过期的糟糕表 现甚至比低效的性能更让人难以接受。故而我们需要在性能与数据正确性间作出权衡。所幸的是.Net Framework 2.0引入了一种新的缓存机制它为我们的“鱼与熊掌兼得”带来了技术上的可行性。 .Net 2.0引入的自定义缓存依赖项特别是基于MS-SQL Server的SqlCacheDependency特性使得我们可以避免“数据过期”的问题它能够根据数据库中相应数据的变化通知缓存并移除那 些过期的数据。事实上在PetShop 4.0中就充分地利用了SqlCacheDependency特性。 4.2 SqlCacheDependency特性 SqlCacheDependency特性实际上是通过System.Web.Caching.SqlCacheDependency类来体现的。 通过该类可以在所有支持的SQL Server版本7.020002005上监视特定的SQL Server数据库表并创建依赖于该表以及表中数据行的缓存项。当数据表或表中特定行的数据发生更改时具有依赖项的数据项就会失效并自动从 Cache中删除该项从而保证了缓存中不再保留过期的数据。由于版本的原因SQL Server 2005完全支持SqlCacheDependency特性但对于SQL Server 7.0和SQL Server 2000而言就没有如此幸运了。毕竟这些产品出现在.Net Framework 2.0之前因此它并没有实现自动监视数据表数据变化通知ASP.NET的功能。解决的办法就是利用轮询机制通过ASP.NET进程内的一个线程以指 定的时间间隔轮询SQL Server数据库以跟踪数据的变化情况。 要使得7.0或者2000版本的SQL Server支持SqlCacheDependency特性需要对数据库服务器执行相关的配置步骤。有两种方法配置SQL Server使用aspnet_regsql命令行工具或者使用SqlCacheDependencyAdmin类。 4.2.1  利用aspnet_regsql工具 aspnet_regsql工具位于Windows\Microsoft.NET\Framework\[版本]文件夹中。如果直接双击该工具的执行文件会弹出一个向导对话框提示我们完成相应的操作 图4-1 aspnet_regsql工具 如图4-1所示中的提示信息说明该向导主要用于配置SQL Server数据库如membershipprofiles等信息如果要配置SqlCacheDependency则需要以命令行的方式执行。以 PetShop 4.0为例数据库名为MSPetShop4则命令为aspnet_regsql -S localhost -E -d MSPetShop4 -ed 以下是该工具的命令参数说明-?  显示该工具的帮助功能-S  后接的参数为数据库服务器的名称或者IP地址-U  后接的参数为数据库的登陆用户名-P  后接的参数为数据库的登陆密码-E  当使用windows集成验证时使用该功能-d  后接参数为对哪一个数据库采用SqlCacheDependency功能-t  后接参数为对哪一个表采用SqlCacheDependency功能-ed  允许对数据库使用SqlCacheDependency功能-dd  禁止对数据库采用SqlCacheDependency功能-et  允许对数据表采用SqlCacheDependency功能-dt  禁止对数据表采用SqlCacheDependency功能-lt  列出当前数据库中有哪些表已经采用sqlcachedependency功能。 以上面的命令为例说明将对名为MSPetShop4的数据库采用SqlCacheDependency功能且SQL Server采用了windows集成验证方式。我们还可以对相关的数据表执行aspnet_regsql命令如aspnet_regsql -S localhost -E -d MSPetShop4 -t Item -etaspnet_regsql -S localhost -E -d MSPetShop4 -t Product -etaspnet_regsql -S localhost -E -d MSPetShop4 -t Category -et 当执行上述的四条命令后aspnet_regsql工具会在MSPetShop4数据库中建立一个名为 AspNet_SqlCacheTablesForChangeNotification的新数据库表。该数据表包含三个字段。字段tableName记 录要追踪的数据表的名称例如在PetShop 4.0中要记录的数据表就包括Category、Item和Product。notificationCreated字段记录开始追踪的时间。 changeId作为一个类型为int的字段用于记录数据表数据发生变化的次数。如图4-2所示 图4-2 AspNet_SqlCacheTablesForChangeNotification数据表 除此之外执行该命令还会为MSPetShop4数据库添加一组存储过程为ASP.NET提供查询追踪的数据表的情况同时还将为使用了 SqlCacheDependency的表添加触发器分别对应Insert、Update、Delete等与数据更改相关的操作。例如Product数 据表的触发器CREATE TRIGGER dbo.[Product_AspNet_SqlCacheNotification_Trigger] ON [Product]    FOR INSERT, UPDATE, DELETE AS BEGIN    SET NOCOUNT ON    EXEC dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure NProductEND 其中AspNet_SqlCacheUpdateChangeIdStoredProcedure即是工具添加的一组存储过程中的一个。当对 Product数据表执行Insert、Update或Delete等操作时就会激活触发器然后执行 AspNet_SqlCacheUpdateChangeIdStoredProcedure存储过程。其执行的过程就是修改 AspNet_SqlCacheTablesForChangeNotification数据表的changeId字段值CREATE PROCEDURE dbo.AspNet_SqlCacheUpdateChangeIdStoredProcedure             tableName NVARCHAR(450)         AS         BEGIN             UPDATE dbo.AspNet_SqlCacheTablesForChangeNotification WITH (ROWLOCK) SET changeId changeId 1             WHERE tableName tableName         END  GO 4.2.2  利用SqlCacheDependencyAdmin类 我们也可以利用编程的方式来来管理数据库对SqlCacheDependency特性的使用。该类包含了五个重要的方法 DisableNotifications为特定数据库禁用 SqlCacheDependency对象更改通知DisableTableForNotifications为数据库中的特定表禁用SqlCacheDependency对象更改通知EnableNotifications为特定数据库启用SqlCacheDependency对象更改通知EnableTableForNotifications为数据库中的特定表启用SqlCacheDependency对象更改通知GetTablesEnabledForNotifications返回启用了SqlCacheDependency对象更改通知的所有表的列表 表4-1 SqlCacheDependencyAdmin类的主要方法 假设我们定义了如下的数据库连接字符串const string connectionStr Serverlocalhost;DatabaseMSPetShop4; 那么为数据库MSPetShop4启用SqlCacheDependency对象更改通知的实现为protected void Page_Load(object sender, EventArgs e){    if (!IsPostBack)   {       SqlCacheDependencyAdmin.EnableNotifications(connectionStr);   }} 为数据表Product启用SqlCacheDependency对象更改通知的实现则为SqlCacheDependencyAdmin.EnableTableForNotifications(connectionStr, Product); 如果要调用表4-1中所示的相关方法需要注意的是访问SQL Server数据库的帐户必须具有创建表和存储过程的权限。如果要调用EnableTableForNotifications方法还需要具有在该表上创建SQL Server触发器的权限。 虽然说编程方式赋予了程序员更大的灵活性但aspnet_regsql工具却提供了更简单的方法实现对SqlCacheDependency的配 置与管理。PetShop 4.0采用的正是aspnet_regsql工具的办法它编写了一个文件名为InstallDatabases.cmd的批处理文件其中包含了对 aspnet_regsql工具的执行并通过安装程序去调用该文件实现对SQL Server的配置。 4.3 在PetShop 4.0中ASP.NET缓存的实现 PetShop作为一个B2C的宠物网上商店需要充分考虑访客的用户体验如果因为数据量大而导致Web服务器的响应不及时页面和查询数据迟迟 得不到结果会因此而破坏客户访问网站的心情在耗尽耐心的等待后可能会失去这一部分客户。无疑这是非常糟糕的结果。因而在对其进行体系架构设计时 整个系统的性能就显得殊为重要。然而我们不能因噎废食因为专注于性能而忽略数据的正确性。在PetShop 3.0版本以及之前的版本因为ASP.NET缓存的局限性这一问题并没有得到很好的解决。PetShop 4.0则引入了SqlCacheDependency特性使得系统对缓存的处理较之以前大为改观。 4.3.1  CacheDependency接口 PetShop 4.0引入了SqlCacheDependency特性对Category、Product和Item数据表对应的缓存实施了SQL Cache Invalidation技术。当对应的数据表数据发生更改后该技术能够将相关项从缓存中移除。实现这一技术的核心是 SqlCacheDependency类它继承了CacheDependency类。然而为了保证整个架构的可扩展性我们也允许设计者建立自定义的 CacheDependency类用以扩展缓存依赖。这就有必要为CacheDependency建立抽象接口并在web.config文件中进行配 置。 在PetShop 4.0的命名空间PetShop.ICacheDependency中定义了名为IPetShopCacheDependency接口它仅包含了一个接口方法public interface IPetShopCacheDependency{          AggregateCacheDependency GetDependency();} AggregateCacheDependency是.Net Framework 2.0新增的一个类它负责监视依赖项对象的集合。当这个集合中的任意一个依赖项对象发生改变时该依赖项对象对应的缓存对象都将被自动移除。AggregateCacheDependency 类起到了组合CacheDependency对象的作用它可以将多个CacheDependency对象甚至于不同类型的 CacheDependency对象与缓存项建立关联。由于PetShop需要为Category、Product和Item数据表建立依赖项因而 IPetShopCacheDependency的接口方法GetDependency()其目的就是返回建立了这些依赖项的 AggregateCacheDependency对象。 4.3.2  CacheDependency实现 CacheDependency的实现正是为Category、Product和Item数据表建立了对应的SqlCacheDependency类型的依赖项如代码所示public abstract class TableDependency : IPetShopCacheDependency{    // This is the separator thats used in web.config    protected char[] configurationSeparator new char[] { , };     protected AggregateCacheDependency dependency new AggregateCacheDependency();    protected TableDependency(string configKey)    {        string dbName ConfigurationManager.AppSettings[CacheDatabaseName];        string tableConfig ConfigurationManager.AppSettings[configKey];        string[] tables tableConfig.Split(configurationSeparator);         foreach (string tableName in tables)            dependency.Add(new SqlCacheDependency(dbName, tableName));    }    public AggregateCacheDependency GetDependency()   {        return dependency;    }} 需要建立依赖项的数据库与数据表都配置在web.config文件中其设置如下add keyCacheDatabaseName valueMSPetShop4/add keyCategoryTableDependency valueCategory/add keyProductTableDependency valueProduct,Category/add keyItemTableDependency valueProduct,Category,Item/ 根据各个数据表间的依赖关系因而不同的数据表需要建立的依赖项也是不相同的从配置文件中的value值可以看出。然而不管建立依赖项的多寡其 创建的行为逻辑都是相似的因而在设计时抽象了一个共同的类TableDependency并通过建立带参数的构造函数完成对依赖项的建立。由于接 口方法GetDependency()的实现中返回的对象dependency是在受保护的构造函数创建的因此这里的实现方式也可以看作是 Template Method模式的灵活运用。例如TableDependency的子类Product就是利用父类的构造函数建立了Product、Category 数据表的SqlCacheDependency依赖public class Product : TableDependency{    public Product() : base(ProductTableDependency) { }} 如果需要自定义CacheDependency那么创建依赖项的方式又有不同。然而不管是创建SqlCacheDependency对象还是自 定义的CacheDependency对象都是将这些依赖项添加到AggregateCacheDependency类中因而我们也可以为自定义 CacheDependency建立专门的类只要实现IPetShopCacheDependency接口即可。 4.3.3  CacheDependency工厂 继承了抽象类TableDependency的Product、Category和Item类均需要在调用时创建各自的对象。由于它们的父类 TableDependency实现了接口IPetShopCacheDependency因而它们也间接实现了 IPetShopCacheDependency接口这为实现工厂模式提供了前提。 在PetShop 4.0中依然利用了配置文件和反射技术来实现工厂模式。命名空间PetShop.CacheDependencyFactory中类DependencyAccess即为创建IPetShopCacheDependency对象的工厂类public static class DependencyAccess{           public static IPetShopCacheDependency CreateCategoryDependency()    {        return LoadInstance(Category);    }    public static IPetShopCacheDependency CreateProductDependency()    {        return LoadInstance(Product);    }    public static IPetShopCacheDependency CreateItemDependency()    {        return LoadInstance(Item);    }    private static IPetShopCacheDependency LoadInstance(string className)    {        string path ConfigurationManager.AppSettings[CacheDependencyAssembly];        string fullyQualifiedClass path . className;        return (IPetShopCacheDependency)Assembly.Load(path).CreateInstance(fullyQualifiedClass);    }}整个工厂模式的实现如图4-3所示  图4-3 CacheDependency工厂 虽然DependencyAccess类创建了实现了IPetShopCacheDependency接口的类Category、Product、 Item然而我们之所以引入IPetShopCacheDependency接口其目的就在于获得创建了依赖项的 AggregateCacheDependency类型的对象。我们可以调用对象的接口方法GetDependency()如下所示AggregateCacheDependency dependency DependencyAccess.CreateCategoryDependency().GetDependency(); 为了方便调用者似乎我们可以对DependencyAccess类进行改进将原有的CreateCategoryDependency()方法修改为创建AggregateCacheDependency类型对象的方法。 然而这样的做法扰乱了作为工厂类的DependencyAccess的本身职责且创建IPetShopCacheDependency接口对象的行为仍然有可能被调用者调用所以保留原有的DependencyAccess类仍然是有必要的。 在PetShop 4.0的设计中是通过引入Facade模式以方便调用者更加简单地获得AggregateCacheDependency类型对象。 4.3.4  引入Facade模式 利用Facade模式可以将一些复杂的逻辑进行包装以方便调用者对这些复杂逻辑的调用。就好像提供一个统一的门面一般将内部的子系统封装起来统一为一个高层次的接口。一个典型的Facade模式示意图如下所示 图4-4 Facade模式 Facade模式的目的并非要引入一个新的功能而是在现有功能的基础上提供一个更高层次的抽象使得调用者可以直接调用而不用关心内部的实现方 式。以CacheDependency工厂为例我们需要为调用者提供获得AggregateCacheDependency对象的简便方法因而创建了 DependencyFacade类public static class DependencyFacade{    private static readonly string path ConfigurationManager.AppSettings[CacheDependencyAssembly];    public static AggregateCacheDependency GetCategoryDependency()    {        if (!string.IsNullOrEmpty(path))            return DependencyAccess.CreateCategoryDependency().GetDependency();        else            return null;    }    public static AggregateCacheDependency GetProductDependency()    {        if (!string.IsNullOrEmpty(path))            return DependencyAccess.CreateProductDependency().GetDependency();        else            return null;        }    public static AggregateCacheDependency GetItemDependency()    {        if (!string.IsNullOrEmpty(path))            return DependencyAccess.CreateItemDependency().GetDependency();        else            return null;    }} DependencyFacade类封装了获取AggregateCacheDependency类型对象的逻辑如此一来调用者可以调用相关方法获得创建相关依赖项的AggregateCacheDependency类型对象AggregateCacheDependency dependency DependencyFacade.GetCategoryDependency(); 比起直接调用DependencyAccess类的GetDependency()方法而言除了方法更简单之外同时它还对CacheDependencyAssembly配置节进行了判断如果其值为空则返回null对象。 在PetShop.Web的App_Code文件夹下静态类WebUtility的GetCategoryName()和GetProductName()方法调用了DependencyFacade类。例如GetCategoryName()方法public static string GetCategoryName(string categoryId){     Category category new Category();     if (!enableCaching)            return category.GetCategory(categoryId).Name;      string cacheKey string.Format(CATEGORY_NAME_KEY, categoryId);      // 检查缓存中是否存在该数据项;     string data (string)HttpRuntime.Cache[cacheKey];     if (data null)     {           // 通过web.config的配置获取duration值;           int cacheDuration int.Parse(ConfigurationManager.AppSettings[CategoryCacheDuration]);           // 如果缓存中不存在该数据项则通过业务逻辑层访问数据库获取;           data category.GetCategory(categoryId).Name;           // 通过Facade类创建AggregateCacheDependency对象;           AggregateCacheDependency cd DependencyFacade.GetCategoryDependency();           // 将数据项以及AggregateCacheDependency 对象存储到缓存中;           HttpRuntime.Cache.Add(cacheKey, data, cd, DateTime.Now.AddHours(cacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.High, null);      }      return data;} GetCategoryName()方法首先会检查缓存中是否已经存在CategoryName数据项如果已经存在就通过缓存直接获取数据否 则将通过业务逻辑层调用数据访问层访问数据库获得CategoryName在获得了CategoryName后会将新获取的数据连同 DependencyFacade类创建的AggregateCacheDependency对象添加到缓存中。 WebUtility静态类被表示层的许多页面所调用例如Product页面public partial class Products : System.Web.UI.Page{    protected void Page_Load(object sender, EventArgs e)    {        Page.Title WebUtility.GetCategoryName(Request.QueryString[categoryId]);    }} 显示页面title的逻辑是放在Page_Load事件方法中因而每次打开该页面都要执行获取CategoryName的方法。如果没有采用缓存机制当Category数据较多时页面的显示就会非常缓慢。 4.3.5  引入Proxy模式 业务逻辑层BLL中与Product、Category、Item有关的业务方法其实现逻辑是调用数据访问层DAL对象访问数据库以获取相 关数据。为了改善系统性能我们就需要为这些实现方法增加缓存机制的逻辑。当我们操作增加了缓存机制的业务对象时对于调用者而言应与BLL业务对象的 调用保持一致。也即是说我们需要引入一个新的对象去控制原来的BLL业务对象这个新的对象就是Proxy模式中的代理对象。 以PetShop.BLL.Product业务对象为例PetShop为其建立了代理对象ProductDataProxy并在GetProductByCategory()等方法中引入了缓存机制例如public static class ProductDataProxy{     private static readonly int productTimeout int.Parse(ConfigurationManager.AppSettings[ProductCacheDuration]);    private static readonly bool enableCaching bool.Parse(ConfigurationManager.AppSettings[EnableCaching]);           public static IListGetProductsByCategory(string category)    {        Product product new Product();         if (!enableCaching)            return product.GetProductsByCategory(category);         string key product_by_category_ category;        IList data (IList )HttpRuntime.Cache[key];         // Check if the data exists in the data cache        if (data null)        {            data product.GetProductsByCategory(category);             // Create a AggregateCacheDependency object from the factory            AggregateCacheDependency cd DependencyFacade.GetProductDependency();             // Store the output in the data cache, and Add the necessary AggregateCacheDependency object            HttpRuntime.Cache.Add(key, data, cd, DateTime.Now.AddHours(productTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);        }        return data;    }} 与业务逻辑层Product对象的GetProductsByCategory()方法相比增加了缓存机制。当缓存内不存在相关数据项时则直接 调用业务逻辑层Product的GetProductsByCategory()方法来获取数据并将其与对应的 AggregateCacheDependency对象一起存储在缓存中。 引入Proxy模式实现了在缓存级别上对业务对象的封装增强了对业务对象的控制。由于暴露在对象外的方法是一致的因而对于调用方而言调用代理对象与真实对象并没有实质的区别。 从职责分离与分层设计的角度分析我更希望这些Proxy对象是被定义在业务逻辑层中而不像在PetShop的设计那样被划分到表示层UI中。 此外如果需要考虑程序的可扩展性与可替换性我们还可以为真实对象与代理对象建立统一的接口或抽象类。然而单以PetShop的表示层调用来看采用 静态类与静态方法的方式或许更为合理。我们需要谨记“过度设计”是软件设计的警戒线。 如果需要对UI层采用缓存机制将应用程序数据存放到缓存中就可以调用这些代理对象。以ProductsControl用户控件为例调用方式如下productsList.DataSource ProductDataProxy.GetProductsByCategory(categoryKey); productsList对象属于自定义的CustomList类型这是一个派生自System.Web.UI.WebControls.DataList控件的类它的DataSource属性可以接受IList集合对象。不过在PetShop 4.0的设计中对于类似于ProductsControl类型的控件而言采用的缓存机制是页输出缓存。我们可以从ProductsControl.ascx页面的Source代码中发现端倪% OutputCache Duration100000 VaryByParampage;categoryId % 与ASP.NET 1.x的页输出缓存不同的是在ASP.NET 2.0中为ASP.NET用户控件新引入了CachePolicy属性该属性的类型为ControlCachePolicy类它以编程方式实现了对 ASP.NET用户控件的输出缓存设置。我们可以通过设置ControlCachePolicy类的Dependency属性来设置与该用户控件相关的 依赖项例如在ProductsControl用户控件中进行如下的设置protected void Page_Load(object sender, EventArgs e){    this.CachePolicy.Dependency DependencyFacade.GetProductDependency();} 采用页输出缓存并且利用ControlCachePolicy设置输出缓存能够将业务数据与整个页面放入到缓存中。这种方式比起应用程序缓存而 言在性能上有很大的提高。同时它又通过引入的SqlCacheDependency特性有效地避免了“数据过期”的缺点因而在PetShop 4.0中被广泛采用。相反之前为Product、Category、Item业务对象建立的代理对象则被“投闲散置”仅仅作为一种设计方法的展示而 “幸存”与整个系统的源代码中。转载于:https://www.cnblogs.com/chenying99/archive/2011/03/14/1983125.html
http://www.zqtcl.cn/news/901954/

相关文章:

  • 聚通达网站建设网站并发要求
  • 网站建设预算申请如何写服装店网页设计素材
  • 做网站设计的公司柳州芜湖又出现一例
  • 重庆网站网站建设东莞市网站建设公司哪家好
  • php做网站如何架构wordpress 排版
  • wordpress免费网站模板下载地址在北京注册公司需要多少钱
  • 做的网站打不开高端网站名字
  • 个人网站建设报告西安网站开发高端网站开发
  • “网站建设:上海珍岛”网站备案信息查询系统
  • 北京哪个公司做网站专业建站培训
  • 郑州知名网站推广网站管理设置
  • 建设工程网站资质人员查询常州模板网站建设价格
  • 自己建网站做app手机网站列表页源码
  • 企业网站模板seo网站建设关键词优化
  • 平面毕业设计作品网站推广普通话ppt
  • p2p网站开发思路方案免费建简单网站
  • 微信朋友圈的网站连接怎么做互联网工程有限公司
  • 高大上企业网站优秀的门户网站
  • 做seo对网站推广有什么作用自己做电商网站吗
  • 网站从哪些方面来做泉州网页搜索排名提升
  • 网站建设可以给公司带来想做网站开发兼职
  • 天津市免费建站精美大气的餐饮类企业网站
  • 购物网站那个信用好又便宜手机模板的网站
  • 建筑企业资质查询网站怎么查网络服务商
  • 汉川市城乡建设局网站企业销售网站建设
  • 梅州建设网站域名购买流程
  • 单页网站与传统网站的区别wordpress对接微信
  • 做公司网站深圳旅游
  • 最好企业网站网站建设 的销售图片
  • 怎么创建网站 免费滴做网站算运营吗