gpt4 book ai didi

asp.net-mvc - MVC Controller 中的单一职责原则。需要批评

转载 作者:行者123 更新时间:2023-12-02 00:14:48 29 4
gpt4 key购买 nike

在我的 MVC4 应用程序中,有些操作需要根据您是否登录(在我的例子中是 FormsAuthentication)而采取不同的行为。

例如,我有一个 AccountController,它有一个方法“RenderAccountAndProfile”。如果注销,相应的局部 View 会显示登录提示和按钮。如果用户已登录,则会显示用户的个人资料链接以及注销按钮。

到目前为止,我在项目中采用的方法是简单地使用 if 语句...

        if (HttpContext.User.Identity.IsAuthenticated)
{
...
}
else
{
...
}

但是,我刚刚创建了我认为是这种方法的相当优雅的替代方法。

我创建了一个名为 AnonymousUsersOnly 的新属性,它非常简单:

public class AnonymousUsersOnlyAttribute : System.Web.Mvc.ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(System.Web.Mvc.ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
return !controllerContext.HttpContext.User.Identity.IsAuthenticated;
}
}

我的 AccountController 类用 Authorize 属性修饰。这使我能够拥有以下代码:

[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
[AnonymousUsersOnly]
[ActionName("RenderAccountAndProfile")]
public ActionResult RenderAccountAndProfile_Anonymous()
{
// create a "logged out" view model
return Content("**NOT LOGGED IN** - LOG IN HERE");
}

[ActionName("RenderAccountAndProfile")]
public ActionResult RenderAccountAndProfile_Authorized()
{
// create a "logged in" view model
return Content("**LOGGED IN** - LOG OUT");
}
}

我非常喜欢这种方法,因为我的操作方法符合 Single Responsibility Principle .每个方法现在只处理登录情况或注销情况。我不再需要任何“if”语句来引导流量。

这也应该使单元测试更容易,因为每个方法现在只关心一个结果,而不是两个。我们可以编写单元测试来分别测试每个结果,调用不同的方法。

很明显,我不能有两个具有相同签名的方法,所以这就是我必须使用 ActionName 属性的原因。

非常感谢您的批评。您认为这是一个优雅的解决方案吗?这种方法的优缺点是什么?这会带来哪些安全隐患/风险?

最佳答案

您这里遇到的问题是策略模式问题。你已经实现了一个(非标准的)策略模式,而且实现非常巧妙。我担心它太聪明了。这种聪明使得代码的作用对于外行来说不那么明显。

顺便说一句,我不想​​打扰。我经常将 Controller 编写为域对象/服务上的非常薄的适配器。因此,我愿意以务实的态度来完善 Controller 的设计。在轻微的设计问题和明显的代码之间做出决定时,总是选择明显的代码。

如果您有更厚的 Controller ,或者出于其他原因真正关心这里的这个问题,您可能会考虑更传统的策略模式,或许可以借助一个抽象工厂来提供基于身份验证状态的不同策略实现。这符合您的设计目标,并且其他程序员(如果他们了解设计模式)会更加熟悉。

综上所述,我认为保留您的聪明解决方案不会对任何事情造成太大伤害。我很想改名;对我来说,拒绝似乎是一个奇怪的动词。也许 AnonymousUsersOnly,这对 future 的程序员来说会更容易交流。

关于asp.net-mvc - MVC Controller 中的单一职责原则。需要批评,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13714250/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com