Questions tagged «abstraction»

使用此标记可以参考硬件抽象,例如Windows如何甚至在不同的硬件上也可以使用相同的API,或者参考通过软件将现实与用户级程序分开的任何其他方法。不应将其用于仿真。

12
如果我们重写SetWidth和SetHeight方法,为什么Square从Rectangle继承会出现问题?
如果Square是Rectangle的一种类型,那么为什么Square无法从Rectangle继承?还是为什么设计不好? 我听说有人说: 如果您使Square从Rectangle派生,那么Square应该可以在您期望矩形的任何地方使用 这里有什么问题?为何Square可以在您期望矩形的任何地方使用?仅当我们创建Square对象,并且重写Square的SetWidth和SetHeight方法时,它才可用,为什么会有任何问题呢? 如果您在Rectangle基类上具有SetWidth和SetHeight方法,并且Rectangle引用指向一个Square,则SetWidth和SetHeight毫无意义,因为设置一个将更改另一个以匹配它。在这种情况下,Square无法通过带有矩形的Liskov替代测试,并且从Square继承Square的抽象是一个不好的选择。 有人可以解释以上论点吗?同样,如果我们在Square中重写SetWidth和SetHeight方法,它是否可以解决此问题? 我也听说过: 真正的问题是我们不是在建模矩形,而是在“舒适的矩​​形”上建模,即在创建后可以修改宽度或高度的矩形(并且我们仍然将其视为同一对象)。如果我们以这种方式看待矩形类,很明显,正方形不是“可接受的矩形”,因为正方形无法重塑,并且仍然是正方形(通常)。在数学上,我们看不到问题,因为在数学环境中可变性甚至都没有意义 在这里,我认为“可调整大小”是正确的术语。矩形是“可调整大小的”,正方形也是如此。我在上述论点中缺少什么吗?可以像调整任何矩形一样调整正方形的大小。

28
为什么某些人认为聪明在编程中有害?
我最近注意到了很多与不同抽象技术有关的问题,并回答说基本上这些技术都是“太聪明了”。我认为,作为程序员的一部分工作是为我们所要解决的问题确定最佳解决方案,而聪明有助于做到这一点。 所以我的问题是:那些认为某些抽象技术过于聪明而不是聪明本身的人,或者是否有其他理由提出反对? 编辑:此解析器组合器是我认为是聪明的代码的示例。我下载了此文件并查看了大约半小时。然后,我在纸上逐步进行了宏扩展并看到了光。现在我了解了,它似乎比Haskell解析器组合器更优雅。

11
为什么使用抽象(例如LINQ)如此禁忌?[关闭]
我是一个独立承包商,因此,我每年要面试3-4次新演出。我现在正处于那个周期之中,尽管我觉得面试进行得很顺利,但还是被拒绝了。今年我发生了两次相同的事情。 现在,我不是一个完美的人,而且我不希望每个组织都适合。就是说,我的平均命中率比平时低,所以我礼貌地向我的最后一个面试官询问一些建设性的反馈意见,他答应了! 根据访问者的说法,最主要的是,我似乎过于倾向于使用抽象(例如LINQ),而不是倾向于较低级别的有机增长算法。 从表面上看,这是有道理的-实际上,这也使其他拒绝也有意义,因为我在那些访谈中也对LINQ感到不满,而且访调员似乎对LINQ并不了解很多(即使他们是.NET)。伙计们)。 因此,现在我要提一个问题:如果我们应该“站在巨人的肩膀上”并使用我们可以使用的抽象(如LINQ),那么为什么有些人认为它是忌讳的呢?如果代码无需花费额外成本即可达到相同的目标,那么将代码“下架”是否有意义? 在我看来,LINQ,即使它是一种抽象,也只是对为实现完全相同的目的而编写的所有相同算法的抽象。只有性能测试可以告诉您您的自定义方法是否更好,但是如果LINQ之类的东西满足要求,为什么首先要编写自己的类呢? 我的意思不是在这里专注于LINQ。我敢肯定,JAVA世界具有可比性,我只是想知道为什么有些人对使用他们自己未编写的抽象的想法感到如此不舒服。 更新 正如Euphoric指出的那样,在Java世界中,没有任何东西可以与LINQ相提并论。 因此,如果您是在.NET堆栈上进行开发,为什么不总是尝试使用它呢?人们是否可能不完全了解它的作用?

4
过多的抽象会不好吗?
作为程序员,我觉得我们的目标是在给定的域模型和业务逻辑上提供良好的抽象。但是这种抽象应该在哪里停止呢?如何在抽象及其所有优点(灵活性,易于更改等)以及易于理解代码及其所有优点之间进行权衡。 我相信我倾向于写过于抽象的代码,但我不知道它有多好。我经常倾向于将其编写为某种微型框架,包括两部分: 连接在微框架中的微模块:这些模块易于理解,开发和维护为单个单元。这段代码基本上代表了实际执行功能的代码,如需求所述。 连接代码;现在我相信这里是问题所在。该代码趋于复杂,因为它有时非常抽象,一开始很难理解。之所以会出现这种情况,是因为这仅仅是纯粹的抽象,实际上基础和业务逻辑是在所提供的代码1中执行的;因此,该代码一旦经过测试就不会更改。 这是编程的好方法吗?难道说,变更代码在许多模块中非常分散,并且很容易理解,而变更代码与抽象POV相比却非常复杂?如果所有代码都统一地复杂(即代码1更复杂和相互链接,而代码2更简单),以使通过它的任何人都可以在合理的时间内理解它,但是更改很昂贵,或者上述解决方案是好的, “更改代码”非常容易理解,调试,更改,“链接代码”有点困难。 注意:这与代码的可读性无关!1和2处的代码都是可读的,但2处的代码具有更复杂的抽象,而代码1则具有简单的抽象。

24
什么是抽象?[关闭]
对于程序员所使用的编程抽象,是否存在公认的定义?[请注意,不要将编程抽象与“抽象”一词的字典定义混淆。]是否存在明确的甚至是数学的定义?有哪些清晰的抽象示例?

4
如何确定抽象级别
今天我正在读一本书,叫做“ Clean code”,在作者谈论每个函数的抽象级别时,我遇到了一段,他将某些代码分类为低/中/高抽象级别。 我的问题是确定抽象级别的标准是什么? 我引用书中的段落: 为了确保我们的函数正在做“一件事情”,我们需要确保我们函数中的语句都处于相同的抽象级别。很容易看到清单3-1是如何违反此规则的。其中的概念具有很高的抽象水平,例如getHtml();。其他处于中间抽象级别的其他变量,例如:String pagePathName = PathParser.render(pagePath); 还有其他一些非常低的级别,例如:.append(“ \ n”)。

9
抽象:解决问题和一般解决方案之间的战争[关闭]
作为一名程序员,我感到自己陷入困境,希望使我的程序尽可能抽象和通用。 这样做通常可以让我重用我的代码,并为可能(或可能不会)再次出现的问题提供更通用的解决方案。 然后我脑海中的声音说,解决问题虚拟化就这么简单!为什么要花比您更多的时间? 我们所有人的确都遇到过这个问题,抽象在您的右肩上,而“解决问题的愚蠢”在左边。 听哪个,多久听一次?您对此有何策略?您应该抽象一切吗?

4
抽象数据类型和数据结构
我很难理解这些术语。我在Google上搜索并在Wikipedia上阅读了一些内容,但我仍然不确定。到目前为止,我已经确定: 抽象数据类型是新类型的定义,描述了其属性和操作。 数据结构是ADT的实现。许多ADT可以实现为相同的数据结构。 如果我认为正确的话,数组作为ADT意味着元素的集合以及作为数据结构的方式,即如何将其存储在内存中。堆栈是具有推入,弹出操作的ADT,但是如果我的意思是我在算法中使用了以数组形式实现的堆栈,那么我们可以说一下堆栈数据结构吗?为什么堆不是ADT?它可以实现为树或数组。

17
通过抽象隐藏细节有什么价值?透明度没有价值吗?
背景 我不是抽象的忠实粉丝。我会承认,人们可以从接口的适应性,可移植性和可重用性中受益。那里确实有好处,我不想质疑这一点,所以让我们忽略它。 抽象还有另一个主要的“好处”,即向该抽象的用户隐藏实现逻辑和细节。论据是您不需要了解细节,并且此时人们应该专注于自己的逻辑。从理论上讲是有道理的。 但是,无论何时维护大型企业应用程序,我总是需要了解更多细节。只是为了确切地找出某物在做什么,就变得越来越麻烦,它不断地深入研究抽象。也就是说,在找到所使用的存储过程之前,必须执行“打开声明”大约12次。 这种“隐藏细节”的心态似乎只是阻碍。我一直希望界面更透明,抽象更少。我可以阅读高级源代码并知道它的作用,但是我永远不知道它是如何执行的,何时执行的,是我真正需要知道的。 这里发生了什么?我曾经使用过的每个系统是否都经过了错误的设计(至少从这个角度而言)? 我的理念 当我开发软件时,我觉得我尝试遵循一种与ArchLinux哲学密切相关的哲学: Arch Linux保留了GNU / Linux系统固有的复杂性,同时使它们井井有条,透明。Arch Linux开发人员和用户认为,试图隐藏系统的复杂性实际上会导致系统更加复杂,因此应避免使用。 因此,我从未尝试将软件的复杂性隐藏在抽象层的后面。我试图滥用抽象,而不是成为抽象的奴隶。 心中的问题 隐藏细节有真正的价值吗? 我们不是在牺牲透明度吗? 这种透明度难道不有价值吗?

11
多少个设计模式和抽象级别是必需的?[关闭]
我怎样才能知道我的软件有太多的抽象和太多的设计模式,或者反过来,我怎么知道它是否应该有更多的抽象呢? 与我合作的开发人员在这些方面的编程方式有所不同。 有些人确实提取每个小功能,尽可能使用设计模式,并不惜一切代价避免冗余。 其他人,包括我在内,都试图更加务实,并编写出并非完全适合每种设计模式的代码,但由于应用了较少的抽象,因此其理解速度更快。 我知道这是一个权衡。我如何知道何时将足够的抽象放入项目中,又如何知道需要更多抽象呢? 例如,当使用Memcache编写通用缓存层时。难道我们真的需要Memcache,MemcacheAdapter,MemcacheInterface,AbstractCache,CacheFactory,CacheConnector,...,或者这是更易于维护和使用仍然只有一半时,好的代码这些类的? 在Twitter中找到了这个: (https://twitter.com/rawkode/status/875318003306565633)

8
框架是否放置过多抽象?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 我已经进行了不到一年的编程,并且在编写系统应用程序,Web应用程序和用于企业/组织的脚本方面有一些经验。但是,我从未真正完成的一件事是使用Django,Rails或Zend之类的框架。 回顾Django框架,我对框架中提取了多少东西感到沮丧。我了解DRY和最少的代码的核心目标,但是对不同模块的过度依赖以及对核心功能的过度抽象有些感觉是这样的: 由于模块/框架的不断变化的性质,使得程序的过时速度非常快, 由于存在大量可用的框架和模块及其所有特质,使得代码难以理解, 除非您已阅读所有文档,否则使代码的逻辑性降低。也就是说,我可以通读一些列表理解和条件逻辑,弄清楚程序在做什么,但是当您看到需要传入任意字符串和字典的函数时,除非您已经是一位高手,否则事情会变得有些难以理解。给定的模块;和: 使得在框架之间进行切换既困难又乏味。在语言之间进行切换已经是一个挑战,但是如果您对语言的核心功能/理念有足够的了解,这是可以管理的。框架之间的切换似乎更多是死记硬背的问题,从某些方面看,这似乎鼓励了这些框架旨在消除的低效率。 我们真的需要在像MySQL查询这样简单的内容上放置50层抽象吗?为什么不使用类似PHP的PDO接口那样的功能,在该接口中可以处理准备好的语句/输入测试,但是通用的SQL查询仍然是该功能的一部分? 这些抽象真的有用吗?功能膨胀是否会使它们无用,从而使应用程序比没有使用框架编写的类似应用程序更加困难?

8
什么时候原始的迷恋不是代码的味道?
最近,我读了很多文章,将原始的痴迷描述为一种代码气味。 避免原始痴迷有两个好处: 它使域模型更加明确。例如,我可以与业务分析师讨论邮政编码,而不是包含邮政编码的字符串。 所有验证都放在一个地方,而不是整个应用程序。 那里有很多文章描述什么是代码气味。例如,我可以看到为这样的邮政编码除去原始的困扰的好处: public class Address { public ZipCode ZipCode { get; set; } } 这是ZipCode的构造函数: public ZipCode(string value) { // Perform regex matching to verify XXXXX or XXXXX-XXXX format _value = value; } 您将打破DRY原则,将验证逻辑放在所有使用邮政编码的地方。 但是,以下对象呢? 出生日期:检查是否大于预期且小于今天。 薪金:检查是否大于或等于零。 您将创建DateOfBirth对象和Salary对象吗?好处是您可以在描述域模型时谈论它们。但是,这是过度工程的一种情况,因为没有太多的验证。是否有一条规则描述了何时以及何时不消除原始的困扰,或者如果可能的话,您应该始终这样做吗? 我想我可以创建一个类型别名而不是一个类,这将有助于上面的第一点。

1
为什么Haskell不具有类型级别的lambda抽象?
是否有一些理论上的原因(例如类型检查或类型推断变得不确定)或实际原因(太难于正确实现)? 目前,我们可以换东西到newtype像 newtype Pair a = Pair (a, a) 然后有 Pair :: * -> * 但是我们不能做这样的事情λ(a:*). (a,a)。 (有一些语言可以使用它们,例如Scala可以。)

7
除了一连串的if语句或switch之外,还有其他更智能的方法吗?
我正在实现一个接收消息的IRC机器人,并且正在检查该消息以确定要调用的函数。有更聪明的方法吗?在我掌握了20条命令之后,它似乎很快就变得一发不可收拾。 也许有一种更好的抽象方法? public void onMessage(String channel, String sender, String login, String hostname, String message){ if (message.equalsIgnoreCase(".np")){ // TODO: Use Last.fm API to find the now playing } else if (message.toLowerCase().startsWith(".register")) { cmd.registerLastNick(channel, sender, message); } else if (message.toLowerCase().startsWith("give us a countdown")) { cmd.countdown(channel, message); } else if (message.toLowerCase().startsWith("remember am routine")) …


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.