首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将IF重构为责任链模式

将IF重构为责任链模式
EN

Code Review用户
提问于 2011-08-20 02:00:40
回答 1查看 881关注 0票数 1

我一直在尝试学习不同的编程模式,而“责任链”则是我无法理解的。有人告诉我,我的特定代码片段将是一个很好的责任链候选人,我想知道是否有人能告诉我如何到达那里?

代码语言:javascript
复制
Public Overrides Sub OnActionExecuting(ByVal filterContext As ActionExecutingContext)

    ''# Set a local variable for the HttpContext.Request. This is going to
    ''# be used several times in the subsequent actions, so it needs to be
    ''# at the top of the method.
    Dim request = filterContext.HttpContext.Request
    Dim url As Uri = request.Url

    ''# Now we get the referring page
    Dim referrer As Uri = If(Not request.UrlReferrer Is Nothing, request.UrlReferrer, Nothing)

    ''# If the referring host name is the same as the current host name,
    ''# then we want to get out of here and not touch anything else. This
    ''# is because we've already set the appropriate domain in a previous
    ''# call.
    If (Not referrer Is Nothing) AndAlso
       (Not url.Subdomain = "") AndAlso
       (Not url.Subdomain = "www") AndAlso
       (referrer.Host = url.Host) Then
        Return
    End If

    ''# If we've made it this far, it's because the referring host does
    ''# not match the current host. This means the user came here from
    ''# another site or entered the address manually.  We'll need to hit
    ''# the database a time or two in order to get all the right
    ''# information.

    ''# This is here just in case the site is running on an alternate
    ''# port. (especially useful on the Visual Studio built in web server
    ''# / debugger)
    Dim newPort As String = If(url.IsDefaultPort, String.Empty, ":" + url.Port.ToString())

    ''# Initialize the Services that we're going to need now that we're
    ''# planning on hitting the database.
    Dim RegionService As Domain.IRegionService = New Domain.RegionService(New Domain.RegionRepository)

    ''# Right now we're getting the requested region from the URI.  This
    ''# is when a user requests something like
    ''# http://calgary.example.com, whereby we extract "calgary" out of
    ''# the address.
    Dim region As Domain.Region = RegionService.GetRegionByName(url.Subdomain)

    ''# If the RegionService returned a region from it's query, then we
    ''# want to exit the method and allow the user to continue on using
    ''# this region.
    If Not region Is Nothing Then
        Return
    End If

    ''# If we've made it this far, it means that the user either entered
    ''# an Invalid Region (yes, we already know the region is invalid) or
    ''# used www. or nothing as a subdomain.  Up until this point, we
    ''# haven't cared if the user is authenticated or not, nor have we
    ''# cared what the full address in their address bar is.  Now we're
    ''# probably going to start redirecting them somewhere.

    ''# First off we need to check if they're authenticated users. If they
    ''# are, we'll just send them on over to their default region.
    If filterContext.HttpContext.User.Identity.IsAuthenticated Then
        Dim userService As New Domain.UserService(New Domain.UserRepository)
        Dim userRegion = userService.GetUserByID(AuthenticationHelper.RetrieveAuthUser.ID).Region.Name

        filterContext.HttpContext.Response.Redirect(url.Scheme + "://" + userRegion + "." + url.PrimaryDomain + newPort + request.RawUrl)

    End If


    ''# Now we know that the user is not Authenticated. So here we check for
    ''# www. If the host has www in it, then we just strip the www and
    ''# bounce the user to the original request.
    If request.Url.Host.StartsWith("www") Then
        Dim newUrl As String = url.Scheme + "://" + url.Host.Replace("www.", "") + newPort + request.RawUrl
        ''# The redirect is permanent because we NEVER want to see www in the domain.
        filterContext.HttpContext.Response.RedirectPermanent(newUrl)

        ''# It's ok for an annonymous browser to view the "Details" of an
        ''# Event/User/Badge/Tag without being assigned to a regions. So
        ''# this is why we strip the www but don't redirect the visitor
        ''# directly over to the "Choose Your Region" view.

    End If

    ''# If we've gone this far, we know the region is invalid, and the
    ''# user needs to be directed to a "choose your region" page.  We're
    ''# not going to do the redirecting here because we want to allow for
    ''# browsing to specific Users/Tags/Badges/Events that are Region
    ''# Agnostic. But if a user tries to view an event listing of any
    ''# sort, we're going to fire them over to the "Choose Your Region"
    ''# page via a separate Attribute attached to only the Actions that
    ''# require it.

End Sub

下面是一个未注释的C#版本:

代码语言:javascript
复制
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var request = filterContext.HttpContext.Request;
    Uri url = request.Url;
    Uri referrer = (request.UrlReferrer != null) ? request.UrlReferrer : null;



    if (((referrer != null)) && (!string.IsNullOrEmpty(url.Subdomain)) && (!(url.Subdomain == "www")) && (referrer.Host == url.Host)) {
        return;
    }


    string newPort = url.IsDefaultPort ? string.Empty : ":" + url.Port.ToString();


    Domain.IRegionService RegionService = new Domain.RegionService(new Domain.RegionRepository());
    Domain.Region region = RegionService.GetRegionByName(url.Subdomain);


    if ((region != null)) {
        return;
    }


    if (filterContext.HttpContext.User.Identity.IsAuthenticated) {
        Domain.UserService userService = new Domain.UserService(new Domain.UserRepository());
        dynamic userRegion = userService.GetUserByID(AuthenticationHelper.RetrieveAuthUser.ID).Region.Name;

        filterContext.HttpContext.Response.Redirect(url.Scheme + "://" + userRegion + "." + url.PrimaryDomain + newPort + request.RawUrl);

    }




    if (request.Url.Host.StartsWith("www")) {
        string newUrl = url.Scheme + "://" + url.Host.Replace("www.", "") + newPort + request.RawUrl;
        //'# The redirect is permanent because we NEVER want to see www in the domain.
        filterContext.HttpContext.Response.RedirectPermanent(newUrl);

    }


}
EN

回答 1

Code Review用户

回答已采纳

发布于 2011-08-20 15:21:07

这种方法不适合于责任链模式,但肯定可以使用它来实现(仅仅为了教育目的):

代码语言:javascript
复制
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //Init
        var referrerRequestHandler = new ReferrerRequestHandler();
        var regionRequestHandler = new RegionRequestHandler();
        var authenticatedRequestHandler = new AuthenticatedRequestHandler(filterContext);
        var wwwRequestHandler = new WwwRequestHandler(filterContext);

        referrerRequestHandler.SetNextHandler(regionRequestHandler);
        regionRequestHandler.SetNextHandler(authenticatedRequestHandler);
        authenticatedRequestHandler.SetNextHandler(wwwRequestHandler);

        //Run
        var request = filterContext.HttpContext.Request;
        referrerRequestHandler.Redirect(request);
    }
代码语言:javascript
复制
    public abstract class RequestHandler
    {
        public void SetNextHandler(RequestHandler nextHandler)
        {
            _nextHandler = nextHandler;
        }

        public void Redirect(HttpRequestBase request)
        {                
            bool handeled = HandleRedirect(request);
            if (!handeled)
            {
                if (_nextHandler != null)
                {
                    _nextHandler.Redirect(request);
                }
            }
        }

        protected abstract bool HandleRedirect(HttpRequestBase request);

        private RequestHandler _nextHandler;
    }
代码语言:javascript
复制
    public class ReferrerRequestHandler : RequestHandler
    {
        protected override bool HandleRedirect(HttpRequestBase request)
        {
            Uri url = request.Url;
            Uri referrer = (request.UrlReferrer != null) ? request.UrlReferrer : null;
            if (((referrer != null)) && (!string.IsNullOrEmpty(url.Subdomain)) && (!(url.Subdomain == "www")) && (referrer.Host == url.Host))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
代码语言:javascript
复制
    public class RegionRequestHandler: RequestHandler
    {
        protected override bool HandleRedirect(HttpRequestBase request)
        {
            Domain.IRegionService RegionService = new Domain.RegionService(new Domain.RegionRepository());
            Domain.Region region = RegionService.GetRegionByName(url.Subdomain);
            if ((region != null))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
代码语言:javascript
复制
    public class AuthenticatedRequestHandler: RequestHandler
    {
        public AuthenticatedRequestHandler(ActionExecutingContext filterContext)
        {
            _filterContext = filterContext;
        }

        protected override bool HandleRedirect(HttpRequestBase request)
        {
            Uri url = request.Url;
            string newPort = url.IsDefaultPort ? string.Empty : ":" + url.Port.ToString();
            if (_filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                Domain.UserService userService = new Domain.UserService(new Domain.UserRepository());
                dynamic userRegion = userService.GetUserByID(AuthenticationHelper.RetrieveAuthUser.ID).Region.Name;
                _filterContext.HttpContext.Response.Redirect(url.Scheme + "://" + userRegion + "." + url.PrimaryDomain + newPort + request.RawUrl);
                return true;
            }
            else
            {
                return false;
            }
        }            

        private readonly ActionExecutingContext _filterContext;
    }
代码语言:javascript
复制
    public class WwwRequestHandler : RequestHandler
    {
        public WwwRequestHandler(ActionExecutingContext filterContext)
        {
            _filterContext = filterContext;
        }

        protected override bool HandleRedirect(HttpRequestBase request)
        {
            Uri url = request.Url;
            if (request.Url.Host.StartsWith("www"))
            {
                string newUrl = url.Scheme + "://" + url.Host.Replace("www.", "") + newPort + request.RawUrl;
                //'# The redirect is permanent because we NEVER want to see www in the domain.
                _filterContext.HttpContext.Response.RedirectPermanent(newUrl);
                return true;
            }
            else
            {
                return false;
            }
        }
        private readonly ActionExecutingContext _filterContext;
    }
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/4250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档