草庐IT

c++ - 派生和破坏封装,还是违反 DRY?

coder 2024-02-14 原文

我有两个 C++ 类:Sequence,就像 std::vectorFile,它是一个 表示机器上文件的字符串序列

Sequence 派生 File 是很容易的事。它的行为完全相同,但增加了读写文件的功能。 File 特定的功能很容易实现,无需将 Sequence 的数据成员标记为 protected 。相反,它们可以是私有(private)的,File 可以使用 Sequence 的公共(public)接口(interface)。到处都是快乐的时光。

我想创建一个 Array 类,在内部管理动态分配的内存。 Array 对象不能调整大小;大小在构造函数中指定。*

这就是事情变得有争议的地方。

从概念上讲,从Array 派生Sequence 是有意义的。正如 File 是一个具有读写文件功能的 Sequence 一样,Sequence 是一个 Array按需调整大小的附加功能。

但有一个关键区别:调整大小函数需要直接访问 Array 正在管理的内存。换句话说,现在必须保护以前私有(private)的成员。

使用 protected 成员而不是私有(private)成员会破坏封装。 ArraySequence 之间的链接是唯一需要它的链接;作品中的其他类只能使用其父类的公共(public)接口(interface)。从这个意义上说,推导是个坏主意。

您可能会争辩说,想要数组的人可以只使用 Sequence 而忽略调整大小的功能。但话又说回来,您可以只使用 File 并忽略读/写功能。这就像买了一台笔记本电脑,但从未将它从办公 table 上移开。这根本没有意义。

最佳举措是什么:派生并可能破坏封装;使 Array 成为一个完全独立的类,并且必须毫无意义地重新实现很多功能;还是完全忘记 Array 而只是让人们使用 Sequence

*请注意,这是一个用于娱乐和教育的项目,因此拥有一个不可调整大小的动态分配数组的实用性无关紧要。

最佳答案

您可能会考虑从稍微不同的方向切入问题。代替继承,也许这个问题可以用模板来解决——具体来说,一个管理集合缓冲区的策略模板。您(至少)有两种实现方式:一种用于固定分配,另一种用于自动调整大小。

这根本不会破坏封装,而且我能看到两者之间几乎唯一的重叠是初始分配可能大致相同,无论是固定的还是可变的。鉴于这是多么微不足道,我怀疑是否值得花很多时间或精力来尝试将其分解出来。理论上可以,但至少在典型情况下,我们谈论的是一行代码,而且是非常简单的一行代码。

暂时回到继承问题,归结为:这非常类似于标准的圆形与椭圆形的情况,其中有足够的相似性使一个看起来像另一个,但最终都不满足 LSP -- 你不能安全地将其中任何一个视为另一个,因此(至少是公共(public)的)继承是不合适的。私有(private)继承不需要遵循 LSP,但通常仅当/如果您需要/想要覆盖基类的虚函数时才有用,这在这里似乎也不太可能。

关于c++ - 派生和破坏封装,还是违反 DRY?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6553734/

有关c++ - 派生和破坏封装,还是违反 DRY?的更多相关文章

  1. ruby-on-rails - rails : keeping DRY with ActiveRecord models that share similar complex attributes - 2

    这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby​​类,但是我如何得到ActiveRecord关联这个类模型

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  4. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  5. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

  6. ruby-on-rails - OS X Mavericks 破坏了 rbenv? - 2

    最近,我安装了OSXMavericks,它似乎弄乱了我的开发环境。我在运行“railsnewfirst_app”后收到此消息:Youruseraccountisn'tallowedtoinstalltothesystemRubygems.Youcancancelthisinstallationandrun:bundleinstall--pathvendor/bundletoinstallthegemsinto./vendor/bundle/,oryoucanenteryourpasswordandinstallthebundledgemstoRubygemsusingsudo.Pass

  7. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  8. ruby - 使用哪个,eruby 还是 erb? - 2

    eruby和erb有什么区别?哪些考虑因素会促使我选择其中之一?我的应用程序正在为网络设备(路由器、负载平衡器、防火墙等)生成配置文件。我的计划是对配置文件进行模板化,在源文件中使用嵌入式ruby​​(通过eruby或erb)来执行诸如迭代生成路由器的所有接口(interface)配置block之类的操作(这些block都非常相似,仅在标签上有所不同和IP地址)。例如,我可能有这样一个配置模板文件:hostnamesample-routerlogging10.5.16.26当通过嵌入式ruby​​解释器(erb或eruby)运行时,会产生以下输出:hostnamesample-rout

  9. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  10. ruby-on-rails - OSX Yosemite 更新破坏了 pow.cx - 2

    升级到OSXYosemite后,我现有的pow.cx安装不起作用。升级到最新的pow.cx无效。通过事件监视器重新启动它也没有成功。 最佳答案 卸载(!)并重新安装解决了这个问题。curlget.pow.cx/uninstall.sh|shcurlget.pow.cx|sh 关于ruby-on-rails-OSXYosemite更新破坏了pow.cx,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/q

随机推荐