Questions tagged «abstraction»

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

6
函数式编程会增加问题和解决方案之间的“代表性差距”吗?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 4年前关闭。 由于机器语言(例如0110101000110101)计算机语言通常已经演化为更高形式的抽象,因此通常将其应用于问题时更易于理解代码。汇编器是对机器代码的抽象,C是对汇编器的抽象,等等。 面向对象的设计似乎非常擅长于使我们能够根据对象对问题进行建模,例如,可以使用Course类,Student类等对大学课程注册系统的问题进行建模。然后,当我们编写解决方案时在OO语言中,我们有类似的类来承担责任,并且通常对设计特别是模块化代码有帮助。如果我将这个问题交给使用OO方法解决此问题的10个独立团队,通常这10个解决方案将具有与该问题相关的类。当您开始接触这些类的耦合和相互作用时,可能会有很多差异,因此不存在“零代表间隙”之类的问题。 我对函数式编程的经验非常有限(没有实际使用,只有Hello World类型的程序)。我没有看到这样的语言如何像OO语言那样轻松地将FP解决方案映射到问题(具有较小的表示差距)。 我了解FP在并发编程方面的优势。但是我是否缺少某些东西,或者FP是否不是要缩小代表差距(使解决方案更容易理解)? 提出另一种方式是:10个不同团队解决同一现实问题的FP代码有很多共同点吗? 摘自维基百科上的抽象(计算机科学)(重点是我的): 函数式编程语言通常会展示与函数相关的抽象,例如lambda抽象(将术语变成某些变量的函数),高阶函数(参数是函数),括号抽象(将术语变成变量的函数)。 由于[某些]现实世界中的问题很难用这种抽象模型来建模,因此代表性的差距可能会增加。 我看到减小代表性差距的另一种方法是将解决方案元素追溯到问题所在。在0年代和1S IN的机器代码是很难追溯,而Student类是容易追溯。并非所有的OO类都可以轻松地跟踪到问题空间,但是许多类都可以。 FP抽象不是总是需要解释以找出他们要解决的问题空间的哪一部分(除了数学问题)?好的-这方面我很好。在查看了更多示例之后,我将看到FP抽象对于在数据处理中表达的问题的一部分非常清晰。 对相关问题的可接受答案UML可以用于对功能程序进行建模吗?-说“功能程序员在图表中没有太多用处。” 我真的不在乎它是否是UML,但是这使我想知道,如果没有被广泛使用的图,那么FP抽象是否易于理解/交流(假设这个答案是正确的)。同样,我对FP的使用/理解水平是微不足道的,因此我了解不需要简单FP程序的图表。 OO设计具有抽象的功能/类/包级别,每个级别都有封装(访问控制,信息隐藏),这使得管理复杂性变得更加容易。这些是使问题从解决方案回到解决方案的要素。 许多答案都谈到了如何以类似于OO的方式在FP中完成分析和设计,但是到目前为止,没有人引用任何高级信息(保罗引用了一些有趣的东西,但它是低级的)。昨天我做了很多谷歌搜索,发现了一些有趣的讨论。以下摘自Simon Thompson(2004)的“重构功能程序”(重点是我的) 在设计面向对象的系统时,理所当然的是,设计将优先于编程。设计将使用诸如Eclipse之类的工具支持的UML之类的系统编写。入门程序员可能会使用BlueJ之类的系统很好地学习视觉设计方法。FAD:Functional Analysis and Design中报告了类似的函数编程方法的工作,但几乎没有其他工作。可能有许多原因。 现有的功能程序具有不需要设计的规模。许多功能程序都很小,但其他功能程序(例如格拉斯哥Haskell编译器)则很实用。 功能程序直接为应用程序领域建模,因此使设计无关紧要。虽然功能语言提供了各种强大的抽象,但是很难说这些提供了对现实世界建模所需的全部和唯一的抽象。 功能程序是作为一系列不断发展的原型而构建的。 在以上引用的博士学位论文中,概述了使用分析和设计方法(ADM)的好处,而与范式无关。但是有人提出ADM应该与实现范例保持一致。也就是说,OOADM最适合用于OO编程,并且不能很好地应用于诸如FP之类的另一范式。我认为这是一个很好的报价,这就是我所说的代表性差距: 人们可以就哪种范式为软件开发提供最好的支持进行详尽的争论,但是当一个范式停留在从问题描述到实施和交付的单一范式中时,就可以实现最自然,有效和有效的开发包。 以下是FAD提出的一组图表: 功能依赖关系图,提供功能及其在实现中使用的功能; 类型依赖图,为类型提供相同的服务;和, 模块依赖关系图,显示系统模块结构的视图。 FAD论文的第5.1节中有一个案例研究,该系统可以自动生成与足球(足球)联赛有关的数据。这些要求具有100%的功能,例如输入足球结果,产生联赛表,得分表,出勤表,在团队之间转移球员,在新结果后更新数据等。没有记录FAD如何解决非功能性要求除了声明“应该以最低的成本允许使用新功能”之外,几乎无法进行测试。 遗憾的是,除了FAD之外,我没有看到任何针对FP提出的现代建模语言(可视化)参考。UML是另一个范例,因此我们应该忘记这一点。

2
DDD-Lite是一种用于依赖注入的模式语言吗?
我偶然发现了格雷格·杨(Greg Young)的演讲DDD项目失败的7个原因,他在7:20提到了他称为DDD-Lite的内容。 概括地说,他基本上说有些人将DDD用作模式语言(实体,存储库,值对象,服务等),而没有做任何其他与DDD相关的事情。他假设.Net中60%或更多的域模型是DDD-Lite。他认为DDD-Lite基本上是在围绕依赖注入构建一种语言,而您实际上并不需要这样做。他说要么完全做DDD,要么做一些简单的事情。否则,他声称一个人正在为构建良好的抽象而进行所有这些工作,但是没有任何实际的好处。 我必须承认,我对DDD的了解不尽如人意,并且还没有尝试使用它。我也没有读过Eric Evan的书。我对依赖注入更加感兴趣,关于此主题的许多书籍和博客都使用Eric Evans的DDD书籍中的术语和参考概念。这是我接触过DDD概念的地方。我一直在阅读的书籍包括: .NET中的依赖注入 Microsoft .Net:为企业设计应用程序 .NET中的Brownfield应用程序开发 如果要进行依赖注入,那么比“ DDD-Lite”更简单的选择是什么?在我看来,建立良好的抽象非常有用,无论人们是否以“ DDD-Lite”方式使用DDD中的概念。(请参阅Mark Seemann的博客文章:接口不是抽象,而是迈向更好的抽象)。我很难相信每个进行依赖注入的人也都在做(或需要做)完整的DDD。我是否以某种方式误解了格雷格·扬(Greg Young)关于DDD-Lite的论点?

3
对OOP中“抽象”的定义感到困惑
我试图理解OOP中“抽象”的定义。 我遇到了一些主要定义。它们都有效吗?其中之一错了吗?我很困惑。(我用自己的话重新写了定义)。 定义1: 抽象是从现实世界中获取一些对象并将其转换为编程术语的概念。如创建Human类,并给予它int health,int age,String name等性质,和eat()等方法。 定义2: 更一般的定义。抽象是一个概念,它发生在软件系统中涉及“使事情变得更加通用/简单/抽象”的任何地方。一些例子: 继承层次结构,其中较高的类更简单或更通用,并定义更通用和抽象的实现。而层次结构中的下层类则更为具体,并定义了更详细的实现。 使用封装从其他类中隐藏类的实现细节,从而使该类对外部软件世界更加“抽象”(更简单)。 定义3 另一个通用定义:抽象是将重点从事物的细节和具体实现转移到事物的类型(即类),可用的操作(即方法)等概念,从而使编程更简单,更通用,更抽象。(这可以在软件系统中的任何位置和任何上下文中发生)。例如,它在封装时发生,因为封装意味着隐藏实现的细节,仅显示事物的类型及其更笼统和抽象的定义。Anotehr示例将使用ListJava中的对象。该对象实际上使用a ArrayList或a 的实现细节LinkedList,但是此信息使用更通用的名称来抽象List。 这些定义是否正确?(我指的是最常规和公认的定义)。

4
厚实模型与 业务逻辑,您在哪里区分?
今天,我与组织中的另一位开发人员进行了激烈的辩论,讨论在何处以及如何向数据库映射的类中添加方法。我们使用sqlalchemy,并且数据库模型中现有代码库的主要部分不过是一袋带有类名的映射属性,几乎是从数据库表到python对象的机械翻译。 在论点中,我的立场是使用ORM的主要价值是可以将低级行为和算法附加到映射的类。模型首先是类,其次是持久性的(使用文件系统中的xml可以持久性,您无需关心)。他的观点是,任何行为都根本就是“业务逻辑”,并且必然属于持久性模型之外的任何地方,而持久性模型仅用于数据库持久性。 我当然确实认为,什么是业务逻辑,应该分开,因为它与实现方法的较低层和域逻辑之间存在一定的区别,我认为这是模型类提供的抽象。在上一段中讨论过,但是我很难理解那是什么。我对API可能有什么更好的理解(在我们的例子中是HTTP“ ReSTful”),因为用户以他们想做的事情调用API,这与他们被允许做的事情以及如何做不同。完成。 tl; dr:使用ORM时,可以或应该在映射类的方法中进行哪些操作,应该忽略哪些内容以驻留在另一层抽象中?

2
您如何处理代码中的抽象理解?
在查看新的代码库时,我喜欢从下至上的方法开始。 我在其中理解一个文件,然后移至下一个抽象。 但是很多时候我发现自己忘记了底层抽象在做什么。 因此,在这一点上,我发现自己陷入了无尽的循环,回到我以前完全理解的文件,然后尝试重新学习它们。同时尝试弄乱彼此之间相互联系的许多其他抽象。 是否有更好的策略来应对这种情况? 我是否应该忘记较低级别的细节,并将其视为既定知识?但是即使如此,很多时候仍需要对底层抽象有一个先前的了解,以了解当前抽象在做什么。

10
下一级别的抽象是什么?[关闭]
按照目前的情况,这个问题并不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 6年前关闭。 由于编程语言最初只使用顺序执行的代码行,后来演变为包含了第一批抽象级别之一的功能,然后创建了类和对象以进一步抽象它。下一级别的抽象是什么? 还有什么比类还抽象的呢?

4
越来越多的高级编程语言的使用是否会导致缺乏计算机体系结构知识的程序员?
引用维基百科的文章“高级编程语言”: 高级编程语言是一种从计算机详细信息中抽象而来的编程语言。与低级编程语言相比,它可能会使用自然语言元素,更易于使用或在平台之间具有更大的可移植性。这些语言隐藏了CPU操作的详细信息,例如内存访问模型和范围管理。 也就是说,随着编程语言水平的提高,程序员与运行程序的硬件之间的距离就越远。 现在,我不知道各个级别的语言使用情况的统计信息,但是我怀疑较高级别的语言正越来越多地取代较低级别的语言。如果是这样,这是否会导致缺乏计算机体系结构知识的程序员?这会对行业造成问题吗?


4
手动进行依赖注入是否可以更好地替代组成和多态性?
首先,我是入门级程序员;实际上,我正在整个夏季完成AS学位,并完成了最终的顶峰项目。在我的新工作中,当我没有什么项目要做(他们正在等待团队中有更多新员工的到来)时,我在等待的过程中会得到一些可供阅读和学习的书籍-一些教科书,其他与其说是“代码完成”,不如说是。看完这些书之后,我转向互联网学习尽可能多的知识,并开始学习SOLID和DI(我们谈论了Liskov的替代原理,但没有其他SOLID想法)。因此,据我所知,我坐下来做得更好,并且开始编写一些代码以手工使用DI(开发计算机上没有DI框架)。 正如我所做的那样,我发现它感觉很熟悉……而且似乎很像我过去使用多态抽象类的组合所做的工作。我在这里想念大图吗?关于DI(至少是手工),还有其他一些东西吗?我了解在某些DI框架的代码中不包含配置的可能性,这些优点在无需重新编译的情况下就具有很大的好处,但是在手工操作时,我不确定它是否与上述内容有所不同...对此有一些了解将非常有帮助!

4
是否抛出异常泄漏了抽象?
我有一个接口方法,在文档中指出它将抛出特定类型的异常。该方法的实现使用引发异常的东西。捕获内部异常,并抛出接口协定声明的异常。这是一个可以更好解释的代码示例。它是用PHP编写的,但是遵循起来非常简单。 // in the interface /** * @return This method returns a doohickey to use when you need to foo * @throws DoohickeyDisasterException */ public function getThatDoohickey(); // in the implementation public function getThatDoohickey() { try { $SomethingInTheClass->doSomethingThatThrowsAnException(); } catch (Exception $Exc) { throw new DoohickeyDisasterException('Message about doohickey failure'); } …

6
哪些更改太大而无法通过适当的设计轻松实现?
这是一个相当模糊的问题,但这是我在阅读有关适当设计的内容时从未感到满意的答案。 通常,在学习面向对象的编程,抽象,分解等方法时,设计的圣杯以及它们始终声称您使用的是开发技术的原因是,这将使您的程序“易于更改” ,“可维护的”,“灵活的”或用于表达这种有效果的概念的任何同义词。通过将ivars标记为私有,将代码拆分为许多小的自包含方法,使接口保持通用,可以使您完全轻松自如地修改程序。 对于较小的更改,这对我来说效果很好。改变类以提高性能所用的内部数据结构从来都不是主要困难,而且独立于API的用户界面端也没有改变,例如重新设计文本输入系统或检修游戏元素的图形。 所有这些更改似乎天生就是独立的。就所涉及的外部代码而言,它们均不涉及对要修改的程序组件的行为或设计进行任何更改。无论您是以程序编写还是以OO样式编写(具有大型功能还是小型功能),即使您只有中等程度的设计,也可以轻松进行这些更改。 但是,每当更改变得繁琐而繁琐时(即,对API进行更改),我的所有宝贵“模式”都无法挽救。巨大的变化仍然很大,受影响的代码仍然受到影响,并且大量的错误产生工作摆在我面前。 所以,我的问题是这个。适当的设计声称能够促进多大的变化?是否有一些其他的设计技术,或者对我来说是未知的,或者是我没有实现,确实确实使粘滞性修改变得简单,还是那个承诺(我听说过这么多不同的范例)仅仅是一个好主意,完全脱离了软件开发的一成不变的真理?我可以添加到工具栏中的“更改工具”吗? 具体来说,导致我进入论坛的问题是:我一直在努力实现一种解释性编程语言(在D中实现,但这无关紧要),并且我决定将闭包的参数设为基于关键字,而不是当前的位置。这就需要修改所有现有的调用匿名函数的代码,幸运的是,这很小,因为我很早就开发了我的语言(<2000行),但是如果我稍后再做出决定,那将是巨大的。在这种情况下,是否可以通过适当的预见性设计使修改变得更容易,或者确定(大多数)变化本质上影响深远?我很好奇这是否是我自己的设计技能的失败-如果是的话,我 明确地说,我绝不怀疑OOP或其他常用的模式。但是,对我而言,它们的优点在于代码库的原始编写而不是维护。继承使您可以很好地抽象出重复的模式,多态性使您可以通过人类理解的函数(哪个类)而不是由机器理解的效果(switch语句的哪个分支)来分离代码,而小的独立函数可以让您以一种非常愉快的“自下而上”的风格写作。但是,我对他们的灵活性表示怀疑。

4
什么是“过早抽象”?
我听过这个短语被扔掉了,对我来说,论点听起来完全是疯了(对不起,如果我在这里是稻草人,那不是我的意图),通常它遵循以下原则: 您不希望在知道一般情况之前先创建一个抽象,否则(1)您可能会将不属于您的东西放在抽象中,或者(2)忽略了重要的事情。 (1)对我来说,这听起来像程序员不够务实,他们已经假设事情会出现在最终程序中,而事实并非如此,因此他们使用的抽象程度很低,问题不是过早的抽象,它是过早的凝结。 (2)忽略重要的事情是一回事,完全有可能在规范中省略了某些事情,后来证明这很重要,解决这个问题的方法不是在发现自己时就浪费自己的资源和浪费资源。猜错了,这是从客户端获取更多信息。 我们应该始终从抽象到具体工作,因为这是最实用的做事方式,而不是相反。 如果我们不这样做,那么我们可能会误解客户,并创造需要更改的东西,但是如果我们仅构建客户以其自己的语言定义的抽象,那么我们就永远不会遇到这种风险(至少远不及承担风险)是在黑暗中带着某种凝结的镜头),是的,客户可能会改变对细节的想法,但是他们最初用来传达他们想要的内容的抽象往往仍然有效。 这是一个示例,假设客户希望您创建一个物品装箱机器人: public abstract class BaggingRobot() { private Collection<Item> items; public abstract void bag(Item item); } 我们正在从客户端使用的抽象中构建一些东西,而没有涉及我们不知道的事情的更多细节。这是非常灵活的,我已经看到这被称为“过早抽象”,而实际上假设套袋是如何实施还为时过早,可以说与客户讨论后,他们希望一次将多个袋装成袋。为了更新班级,我只需要更改签名,但是对于自下而上的人可能需要进行大范围的系统检修。 没有过早的抽象,只有过早的凝结。这句话有什么问题?我的推理的缺陷在哪里?谢谢。

4
是否应该从页面本身抽象数据库查询?
当用PHP编写页面生成时,我经常发现自己写了一些乱七八糟的数据库查询文件。例如,我可能有一个查询来直接从数据库中获取有关帖子的一些数据以显示在页面上,如下所示: $statement = $db->prepare('SELECT * FROM posts WHERE id=:id'); $statement->bindValue(':id', $id, PDO::PARAM_INT); $statement->execute(); $post = $statement->fetch(PDO::FETCH_ASSOC); $content = $post['content'] // do something with the content 这些快速的一次性查询通常很小,但是有时我最终会遇到很大一部分数据库交互代码,这些代码看起来看起来很混乱。 在某些情况下,我通过创建一个简单的函数库来处理与帖子相关的数据库查询来解决此问题,并将该代码块简化为简单的代码: $content = post_get_content($id); 那太好了。或者至少直到我需要做其他事情为止。也许我需要获取五个最新帖子才能显示在列表中。好吧,我总是可以添加另一个功能: $recent_posts = post_get_recent(5); foreach ($recent_posts as $post) { ... } 但这最终会使用SELECT *查询,无论如何我通常通常并不需要它,但是它通常太复杂而无法合理地抽象。最终,我将获得针对每个用例的庞大的数据库交互功能库,或者在每个页面的代码中包含一系列混乱的查询。即使建立了这些库,我也会发现自己需要做一个以前从未使用过的小联接,而且突然我需要编写另一个高度专业化的函数来完成这项工作。 当然,我可以将这些功能用于一般用例和特定交互的查询,但是,一旦我开始编写原始查询,我便开始回落到直接访问所有内容的位置。要么这样做,要么我会变得懒惰,并且将开始在PHP循环中执行操作,无论如何,它们实际上应该直接在MySQL查询中直接完成。 我想问一下那些具有编写Internet应用程序的经验的人:可维护性的提高是否值得额外的代码行以及抽象可能带来的低效率?还是简单地使用直接查询字符串是处理数据库交互的可接受方法?

5
太多的抽象使得代码难以扩展
我在代码库中感觉到太多抽象(或者至少是处理它)时遇到了问题。代码库中的大多数方法已被抽象为采用代码库中最高的父级A,但是此父级的子级B具有新属性,该属性会影响其中某些方法的逻辑。问题在于这些属性无法在那些方法中检查,因为输入被抽象为A,而A当然没有此属性。如果我尝试创建一个新的方法来不同地处理B,则会被调用以进行代码复制。我的技术负责人的建议是创建一个使用布尔参数的共享方法,但是这样做的问题是,有些人将其视为“隐藏的控制流”,其中共享方法具有的逻辑对于将来的开发人员可能并不明显。 ,并且即使需要添加将来的属性,即使将其分解为较小的共享方法,该共享方法也会变得过于复杂/复杂。这也增加了耦合,降低了凝聚力,并且违反了我团队中有人指出的单一责任原则。 本质上,此代码库中的许多抽象有助于减少代码重复,但是当使它们采用最高抽象时,这会使扩展/更改方法变得更加困难。在这种情况下我该怎么办?尽管其他人不能就他们认为的好事达成共识,但我还是要怪罪于我,这最终伤害了我。

3
有关方法参数类型,返回类型和属性类型的具体性的规则
前一段时间,我读到一种关于方法参数类型,返回类型和属性类型的具体性的“经验法则”,但我只是不记得了。 它说了一些有关使返回类型尽可能具体,而参数类型尽可能抽象的事情……反之亦然。 我不知道这实际上是一个好建议还是坏建议,因此,如果您对此有自己的想法,请发表评论。 干杯。

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.