【问题标题】:How to determine if passing in an object is better than several parameters (int, string, etc) [closed]如何确定传入一个对象是否比几个参数(int、string等)更好[关闭]
【发布时间】:2017-01-15 17:30:54
【问题描述】:

我有一个名为“User”的类/对象,它有大约十几个属性(例如:UserGUID、UserName 等)。它有一个构造函数、静态方法、一些其他的辅助/支持方法等等。

该网站有数百个函数/方法,其中 2+ 参数来自用户对象。例如:

public string HelloWorld(Guid userGUID, Guid accountGUID, bool somethingElse)
{
    //Do something
}

我真的想传入 User 对象本身以使调用更清晰,而不必在每次需要来自 User 对象的新值时不断添加参数。像这样:

public string HelloWorld(User user)
{
    //Do something
    Guid userGUID = user.UserGUID;
}

所以我的问题是,在什么时候传入对象好/坏与传入几个参数?它取决于物体的大小吗?我如何确定什么是“太大”与“好”?是参数的数量吗?多少参数太多了?

【问题讨论】:

  • 这可能应该(并且可能会)被关闭,因为它主要是基于意见的。也就是说,我的两分钱是对象(特别是那些由接口表示的对象)允许变化,API 的扩展而不会给调用者带来严重的成本,以及更好的封装。更多地使用对象并尽早使用它们。
  • 因此,将对象(甚至是大对象)传递给方法与传递多个/多个参数相比,没有负面性能?
  • 在您的情况下使用参数。它更干净、更独立。人们可以很容易地看到他需要提供什么作为论据。对于第二选择,最好在函数完全依赖于用户对象时进行。在你的情况下,它只是使用一些
  • @Losbear 传递对象只会复制对象的引用。所以没关系。但我不推荐上面提到的。
  • @Losbear is User object is your viewmodel ?

标签: c# asp.net asp.net-mvc-4 oop


【解决方案1】:

您应该考虑该方法应该做什么。方法为什么存在?

方法的语义将决定它的参数。因此,例如,如果 HelloWord 应该打印出一些内容,例如 userIdsomething else,那么签名应该包含 userIdsomething else 作为参数。

另一方面,如果HelloWord 应该打印出一些关于User 的信息,那么方法签名应该将对象 User 作为参数。

这完全取决于方法语义。

【讨论】:

  • 明白,但没那么简单。有些方法是返回单个值但需要多个参数来构造该值的简单方法。其他方法执行由传入的参数确定的一堆事情(例如,构建报告等)。一些方法不断得到改进 - 客户不断要求添加新功能,但为了使方法做到这一点,我现在必须添加另一个参数等。这就是为什么我试图确定什么是“断点”
  • 每种方法都应该做一件事——而且只做一件事。因此,如果您有方法在传递 20 个参数的情况下做 100 种不同的事情,那就有问题了。尝试对您的方法进行单元测试,这将帮助您考虑代码的模型
【解决方案2】:

在 Clean Code 中,Robert Martin 说首选 0 个参数,1 或 2 个参数是可以接受的,3 个太多了。

在我看来,只要你在同一个过程中,我认为传递对象比传递参数更可取。您不希望发送(或接收)超出另一个进程(例如 Web 服务)所需的内容。

我强烈推荐 Clean Code,这是一本很好的读物,并且对结构有很多话要说。

【讨论】:

  • 我会看看“清洁代码”——听起来很有趣。 qwr 和 Travis 说,我倾向于根据您的内容将参数保留在适当的位置 - 主要是基于这样的基本原则,即只要您通过的次数超过了您将要使用的次数,就会失去效率。谢谢大家!
【解决方案3】:

这里有一个非常重要的区别,这不是意见。

我有一个名为“User”的类/对象,它有十几个属性

鉴于上述情况,如果您当时允许(User user) 而不是只允许(Guid userGUID, Guid accountGUID, bool somethingElse),那么您刚刚引入了一个安全漏洞。

通过发布User 类的额外名称,客户端将能够发送比他们应该访问的更多的数据。例如,如果您使整个类可用(并且它具有外部关系),则客户端可以以这种方式更改外部导航属性键。客户端也可以根据存储在该类中的信息更改时间戳,甚至逻辑分隔。

如果您允许整个类都被接受,那么防止这种类型的违规行为很容易,您只需要手动检查每个属性以确保它没有被错误发送,或者只选择它的子集来筛选它发送的信息。不管怎样,这都是个坏主意。

虽然使用具有与所示 3 相同属性的 User 类可能没有区别,但如果不选中,允许具有比 3 更大的集合的 User 类的模型绑定可能会出现问题。

【讨论】:

  • 对于我的用户对象,只有在用户的 cookie 被读取、解密并针对我的数据源进行身份验证后,才会创建对象的实例。然后,用户对象仅在后端用于处理请求,因此极不可能被黑客入侵或注入。但我确实听到了你关于给予该方法“比它需要的更多的权力”的观点——这可能会在未来引入问题。感谢您的意见!
  • @Losbear - 经过身份验证的客户端是最容易导致问题的客户端。
猜你喜欢
  • 1970-01-01
  • 2022-12-04
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-05
相关资源
最近更新 更多