将一组相关的属性包装到其自己的struct / class中是一种好习惯吗?


10

用Swift编写User对象,尽管我的问题与任何强类型语言有关。用户可以拥有一堆链接(FacebookProfile,InstagramProfile等)。有关此问题。

  1. 将链接包装在其自己的对象中是一种好习惯吗?
    struct用户{
       var firstName:字符串
       var lastName:字符串
       var email:string
       var链接:链接
    }
    结构链接{
       var facebook:字符串
       var instagram:字串
       var twitter:字符串 
    }

还是应该松散?从技术上讲,我知道这两种方法都很好,但是总体上想知道是否有推荐的方法,尤其是为了提高可读性。

struct User { 
   var firstName: string
   var lastName: string
   var email: string
   var facebookLink: string
   var twitterLink: string
   var instagramLink: string
}
  1. 在这种情况下,链接应该是集合/列表吗?我认为它不应该是一个列表,因为有固定数量的链接选项可用,并且数量不会增加。我的想法对吗?

  2. 将我的网络方法放置在User对象(例如getUsers,getUser,updateUser)内是否是一种好习惯?

我知道这些可能是主观的,但是我试图了解在类似情况下的最佳实践是什么。将不胜感激任何指针。

Answers:


30

您要么需要

  • 零的东西
  • 一件事,或者
  • 任意数量的东西。

令您震惊的是,您的设计预测到所需链接的数量将始终为3,并且您永远知道它们的名字。

我讲的是所谓的零一无穷大法则。乍一看可能并不明显,但这就是告诉我您的设计对未来不宽容的原因。

如果这些链接中有一些特别的东西,我会有所不同。访问Facebook链接时我会做一些与众不同的特殊操作,而对于Twitter链接则不做。那会使他们与众不同。但这未在代码中指出。

这就是为什么我不被电子邮件字符串打扰的原因。我知道使用的方式与链接不同。

因此,直到我有理由不同地使用这些链接的理由之前,我还是站在链接集合的一边。


4
FacebookProfile, InstagramProfile, ...我认为OP已经回答了这个问题。它的语言告诉我们,用户可能没有一个或多个与社交网络相关的个人资料。但是他/她内部的程序员已经将此元素变成了纯粹的链接。为什么不收藏Profiles?我同意蜜饯橙。您对未来承担了太多的责任。新的社交网络可能会出现。实际的可能会消失。用户可以从一个网络转到另一个网络。
Laiv

这是一个猜测。假设您要将这些配置文件用于社交登录。有了组件Profile,我们就可以从哪里开始。使用这些配置文件在何处封装有关身份验证和当前会话的信息。这可能被认为是YAGNI或过度设计,但没有任何考虑的余地,请查看是否可能要求这些功能或它们是否可以为我们的应用程序提供价值。如果不是,则将其丢弃。
Laiv

1
@Prabhu取决于您为什么要限制它。我的猜测只适合GUI。没关系 但不要因为GUI而限制数据结构。GUI随即改变。数据结构的更改成本很高。第一次使它们正确是值得的。
candied_orange

2
这才是重点。只需采用那些将使将来的更改变得不那么痛苦的结构即可。不多不少。我们(蜜饯和我)之所以这样说,是因为我们(我相信)经常遇到类似的情况,并且预见了可能会发生变化或演变的特征。最终,您距离该项目及其未来前景更近。
Laiv

1
@Prabhu:请注意,您问的是有关良好做法的问题,而不是它是否是针对特定情况的最简洁方法。我通常会避免过度设计,但是将来维护(添加/删除链接,更新实体类定义等)的成本远远超过实现链接集合的成本。如果你叫你列link1link2link3,需要收集会更明显。但是,您为列指定了更有意义的名称这一事实并不会改变它是重复数据的集合这一事实。
平坦

6

您即将陷入“我看到技术上的可能性”陷阱。

仅仅因为您看到了项目之间的共同特征,并不意味着对它们进行一些汇总是有意义的。聚合应该意味着什么。不在技术层面上,而是在您的问题范围内。

它们都很好,但是在用户类的上下文中,这意味着什么吗?不会。这与使用名为“字符串”和“数字”的类进行子分组一样毫无意义。

这种事情的麻烦在于它会模糊您的模型。它迫使代码阅读器在对领域完全了解之前,将有意义的内容从无意义的内容中分离出来。

没有人谈论过用户的链接。如果您要调用聚合SocialNetworkId,则可能会有所不同。因为这实际上意味着某些东西,所以它将是User的真实属性,而不是任意的技术收藏。


正是我的疑问促使我提出了这个问题。不同链接之间的唯一关系是它们可能会在UI中一起显示。因此,在这种情况下,您建议不要将它们放在单独的对象中,而应将它们直接放在User对象下?
Prabhu

1
在这种情况下,我认为这不会有所帮助。您还没有一个问题,那就是增加一层复杂性是合理的。如果您拥有更多的属性,则可能在分组工作方面有所收获(为组分配了适当的名称)。但是,如果没有上下文,很难说出什么是合适的。底线是它应该使事情变得容易。了解和/或继续进行开发过程中的下一步。
马丁·马特

我一般喜欢避免过度工程,但我纳闷:你会说同样的事情,如果OP命名了他的田地link1link2link3?数据结构的设计与字段的名称无关,因此我的示例在功能上是等效的。这是面向未来的问题。YAGNI通常会适用,但如果有的话,社交媒体已证明自己很容易受到病毒式传播和变化的影响。避免对每个新的流行社交媒体网站进行重新开发似乎是可取的。否则,您可能会陷入“还有一个领域?”的风险。陷阱,这会造成巨大的债务。
扁平的

1

总的来说,struct如果您可能对每个链接都应用类似的操作,尤其是始终对所有链接执行相同的操作,则我认为将链接单独设置是合理的。如果它们在您的应用程序中出于无关目的,那么我将它们分开。例如,如果他们是用户的主页,他们的健康保险提供商的网站以及指向他们最喜欢的新闻网站的链接,那么由于它们似乎无关,我可能不会将它们组合在一起。但是对于3个社交媒体网站,似乎它们在应用程序中的处理方式类似,因此应该将它们组合在一起。我会使用比起更具描述性的名称Links。(什么类型的链接?在您的应用中出于什么目的?)

我同意您对#2的看法。如上所述,如果数量增加或变得可变,列表或其他集合将是一个不错的选择,但不适用于您描述的场景。

我不会将网络方法放置在保存由网络检索到的数据的对象中。数据来自何处以及如何获取通常与课程的主要目的无关。如果将来您想从磁盘中获取一些数据怎么办?还是要用户输入?沿着这条路走得足够远,一个简单的User类必须具有用于处理数据输入和检索的所有可能方法的代码。只需让一个User类在内存中保留并维护数据即可。其他所有内容都可以由更合适的类处理。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.