- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我以前的 C++ 工作中,我们总是非常小心地封装成员变量,并且只在绝对必要时才将它们作为属性公开。我们有非常具体的构造函数来确保你在使用它之前完全构造了对象。
如今,使用 ORM 框架、依赖注入(inject)、序列化等,似乎您最好只依赖默认构造函数并在属性中公开有关您的类的所有内容,以便您可以注入(inject)内容,或构建和填充对象更动态。
在 C# 中,对象初始值设定项更进一步,它使您能够基本上定义自己的构造函数。 (我知道对象初始值设定项并不是真正的自定义构造函数,但我希望你明白我的意思。)
这个方向是否有任何普遍的担忧?封装似乎开始变得不那么重要,而有利于便利。
编辑:我知道您仍然可以仔细封装成员,但我只是觉得当您尝试创建某些类时,您要么必须坐下来仔细考虑如何封装每个成员,或者只是将其作为属性公开,并担心它稍后如何初始化。现在似乎最简单的方法是将事物作为属性公开,而不是那么小心。也许我完全错了,但这只是我的经验,尤其是新的 C# 语言功能。
最佳答案
我不同意你的结论。有许多很好的方法可以将上述所有技术封装在 c# 中,以保持良好的软件编码实践。我还要说这取决于您正在查看谁的技术演示,但最终归结为减少对象的状态空间,以便您可以确保它们始终保持不变。
拿 对象关系框架 ;它们中的大多数允许您指定它们将如何水合实体;例如,NHibernate 允许您这样说 access="property"
或 access="field.camelcase"
和类似的。这允许您封装您的属性。
依赖注入(inject) 适用于您拥有的其他类型,主要是那些不是实体的类型,即使您可以以一些非常好的方式组合 AOP+ORM+IOC 来改善这些事物的状态。如果您正在构建一个数据驱动的应用程序,IoC 通常在域实体之上的层使用,我猜您是这样,因为您在谈论 ORM。
它们(“它们”是应用程序和域服务以及程序的其他内在类)暴露了它们的依赖关系,但实际上可以在比以前更好的隔离下进行封装和测试,因为按契约(Contract)设计/按接口(interface)设计的范式在基于模拟的测试(与 IoC 结合)中模拟依赖项时,您经常使用它,它将使您转向类作为组件的“语义”。我的意思是:每一个类,当使用上述方法构建时,都会被更好地封装。
为 urig 更新:这适用于暴露混凝土 依赖项 并暴露接口(interface)。首先关于接口(interface):我在上面暗示的是具有依赖关系的服务和其他应用程序类可以与 OOP 依赖于契约(Contract)/接口(interface)而不是特定的实现。在 C/C++ 和较旧的语言中,没有接口(interface),抽象类只能到此为止。接口(interface)允许您将不同的运行时实例绑定(bind)到同一个接口(interface),而不必担心泄漏内部状态,这是您在抽象和封装时试图摆脱的。使用抽象类,您仍然可以提供类实现,只是您无法实例化它,但是继承者仍然需要了解您的实现中的不变量,这可能会弄乱状态。
其次,关于作为属性的具体类:您必须警惕什么类型的类型 ;) 作为属性公开。假设您的实例中有一个 List;然后不要将 IList 作为属性公开;这可能会泄漏,您不能保证接口(interface)的使用者不会添加或删除您依赖的东西;而是公开诸如 IEnumerable 之类的内容并返回 List 的副本,或者甚至更好,将其作为方法执行:
公共(public) IEnumerable MyCollection { 获取 { 返回 _List.Enum();并且您可以 100% 确定同时获得性能和封装。没有人可以添加或删除该 IEnumerable,您仍然不必执行昂贵的数组复制。对应的辅助方法:
static class Ext {
public static IEnumerable<T> Enum<T>(this IEnumerable<T> inner) {
foreach (var item in inner) yield return item;
}
}
关于frameworks - 框架时代的封装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/559953/
我想通过添加一个带有 transition = 0s 的类但更改颜色来使用 jQuery 运行 CSS 动画,然后立即删除该类(使用原始 transition = 2s)它逐渐变为原始颜色。 下面是我
最近两年,互联网+的概念可谓十分火爆。所谓“互联网+”,其实质就是把互联网大平台和各行各业进行有机结合,建立一个新的商业生态,对于传统企业来说,互联网+的第一步就是有一个企业网站,将自己推广出去
每天我都更喜欢 Postgres,今天我发现了函数“age”。它不仅选择年份,还选择月份和日期。太棒了! 46 years 10 mons 18 days 现在我想知道是否有一个函数可以定义“年”、“
我正在 秒 内从服务器接收数据,我想将其转换为最新数据。 但我收到的秒数不是自 UNIX 纪元 01/01/1970 以来,而是 01/01/2000。 通常我会使用: SimpleDateForma
如果在 matlab 中使用可变时间步长求解器,例如 ODE45 - 我将为输出定义一个时间跨度,即 times = [0 50],matlab 将返回不同时间步长的结果介于 0 和 50 之间。 但
因此,System.currentTimeMillis 以 UTC 时区返回毫秒。 DateTime.getmillis 是否与我所知道的几乎所有图书馆都一样,因为纪元总是在 UTC 中? joda-
Hadoop 2.0 引入了 YARN,取代了 Job Tracker 和 Task Tracker 的任务。 YARN 由资源管理器(调度器、应用程序管理器...)、节点管理器和应用程序管理器组成。
在 ViewModel 和 one activity multiple fragments 概念时代,Activity 与 Fragment 中放置 Toasts、Snackbars 有什么建议。 很
许多 Android 讨论都集中在(显然是著名的)Fingerpaint 示例上: https://stackoverflow.com/a/16650524/294884 我从哪里得到它,与 Andr
在(最终)向我的 Facebook 应用程序添加一些分析并意识到英语在我的用户语言列表中排名靠后后,我开始研究 official docs on internationalization . 但是,文
我是一名优秀的程序员,十分优秀!