DotNet Framework源代码中的模式(七)——Factory Method(工厂模式)

 

定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类。

DotNet Framework源代码中的模式(七)——Factory Method(工厂模式)_第1张图片 

.NET Framework 2.0 System.WebSystem.Web.UI中类为例

DotNet Framework源代码中的模式(七)——Factory Method(工厂模式)_第2张图片 

System.Web.IHttpHandler

public   interface  IHttpHandler
{
    
bool  IsReusable {  get ; }
    
void  ProcessRequest(HttpContext context);
}

 

System.Web.IHttpHandlerFactory2

 

public   interface  IHttpHandlerFactory2
{
    IHttpHandler GetHandler(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath);
}

 

System.Web.UI.Page

Code
public class Page : TemplateControl, IHttpHandler
{
    
//
    public bool IsReusable
    {
        
get { return false; }
    }

//

    
public virtual void ProcessRequest(HttpContext context)
    {
        
//
}
//
}

 

System.Web.UI.PageHandlerFactory

Code
public class PageHandlerFactory : IHttpHandlerFactory2 

    
private bool _isInheritedInstance;

    
protected internal PageHandlerFactory() 
    {
        
// Check whether this is the exact PageHandlerFactory, or a derived class 
        _isInheritedInstance = (GetType() != typeof(PageHandlerFactory));
    } 
 
    
public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path) 
    {
        Debug.Trace(
"PageHandlerFactory""PageHandlerFactory: " + virtualPath); 

        
// This should never get called in ISAPI mode but currently is in integrated mode
        
// Debug.Assert(false);
 
        
return GetHandlerHelper(context, requestType, VirtualPath.CreateNonRelative(virtualPath), path);
    } 
 
    IHttpHandler IHttpHandlerFactory2.GetHandler(HttpContext context, String requestType,
        VirtualPath virtualPath, String physicalPath)
    { 

        
// If it's a derived class, we must call the old (less efficient) GetHandler, in
        
// case it was overriden
        if (_isInheritedInstance) { 
            
return GetHandler(context, requestType, virtualPath.VirtualPathString, physicalPath);
        } 
 
        
return GetHandlerHelper(context, requestType, virtualPath, physicalPath);
    } 

    
public virtual void ReleaseHandler(IHttpHandler handler) { }

    
private IHttpHandler GetHandlerHelper(HttpContext context, string requestType, 
        VirtualPath virtualPath, 
string physicalPath) 
    {
 
        Page page 
= BuildManager.CreateInstanceFromVirtualPath( 
            virtualPath, 
typeof(Page), context, true /*allowCrossApp*/true /*noAssert*/as Page;
        
if (page == null
            
return null;

        page.TemplateControlVirtualPath 
= virtualPath;
 
        
return page;
    }  
}

 

默认Web.Config配置

Code
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<!--  -->
  
<system.web>
    
<!--  -->
    
<httpHandlers>
      
<!--  -->
      
<add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="true"/>
      
<add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="true"/>
      
<add path="*.asmx" verb="*" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="false"/>
      
<!--  -->
    
</httpHandlers>
    
<!--  -->
  
</system.web>
  
<!--  -->
</configuration>

 

IHttpHandlerFactory2IHttpHandler的工厂,通过它来生成不同的HttpHandler对象。

HttpHandler是一个HTTP请求的真正处理中心,也正是在这个HttpHandler容器中,ASP.NET Framework才真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。一个HTTP请求都是最终交给一个HttpHandler容器中的ProcessRequest方法来处理的。

HttpHandlerFactory,是一个HTTP请求到达这个HttpHandler Factory时,HttpHandlerFactory会提供出一个HttpHandler容器,交由这个HttpHandler容器来处理这个HTTP请求。对于ASPX页面,ASP.NET Framework在默认情况下是交给System.Web.UI.PageHandlerFactory这个HttpHandlerFactory来处理的。

 

在以下情况下,适用于工厂方法模式:

1. 当一个类不知道它所必须创建的对象的类的时候。

2. 当一个类希望由它的子类来指定它所创建的对象的时候。

3. 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

你可能感兴趣的:(DotNet Framework源代码中的模式(七)——Factory Method(工厂模式))