框架是否放置过多抽象?[关闭]


24

我已经进行了不到一年的编程,并且在编写系统应用程序,Web应用程序和用于企业/组织的脚本方面有一些经验。但是,我从未真正完成的一件事是使用Django,Rails或Zend之类的框架。

回顾Django框架,我对框架中提取了多少东西感到沮丧。我了解DRY和最少的代码的核心目标,但是对不同模块的过度依赖以及对核心功能的过度抽象有些感觉是这样的:

  1. 由于模块/框架的不断变化的性质,使得程序的过时速度非常快,

  2. 由于存在大量可用的框架和模块及其所有特质,使得代码难以理解,

  3. 除非您已阅读所有文档,否则使代码的逻辑性降低。也就是说,我可以通读一些列表理解和条件逻辑,弄清楚程序在做什么,但是当您看到需要传入任意字符串和字典的函数时,除非您已经是一位高手,否则事情会变得有些难以理解。给定的模块;和:

  4. 使得在框架之间进行切换既困难又乏味。在语言之间进行切换已经是一个挑战,但是如果您对语言的核心功能/理念有足够的了解,这是可以管理的。框架之间的切换似乎更多是死记硬背的问题,从某些方面看,这似乎鼓励了这些框架旨在消除的低效率。

我们真的需要在像MySQL查询这样简单的内容上放置50层抽象吗?为什么不使用类似PHP的PDO接口那样的功能,在该接口中可以处理准备好的语句/输入测试,但是通用的SQL查询仍然是该功能的一部分?

这些抽象真的有用吗?功能膨胀是否会使它们无用,从而使应用程序比没有使用框架编写的类似应用程序更加困难?


22
关键字:as a relatively inexperienced programmer-您制作软件的时间越长,花更少的时间重新发明轮子,而在家中做自己喜欢的事情的时间就越多,您将获得更多的收益。
sergserg 2013年

13
Do we really need to put like 50 layers of abstraction on top of something as simple as a MySQL query?-首先,一个好的框架是一层抽象(内部可能是2层或3层),其次,“就像MySQL查询一样简单”实际上涉及很多抽象。即使从解释语言执行的查询已经到达数据库服务器,您仍然可以通过引擎通过数据库查询到通过物理存储通过文件系统查询的数据库。简而言之:是的,我们需要抽象,因为它们可以防止爆炸。
back2dos

7
FWIW,是的,有时我们超过了管道系统。我使用框架完成工作的次数比我原先想的要少。有时编写您自己的代码可以使设计更简单,更适合问题域并获得更好的性能,而不会造成许可问题。
罗伯特·哈维

2
那里有许多微型框架。这些是轻量级框架,有些人觉得它们更具吸引力。例如:flask.pocoo.org。我没用过
ipaul

这个问题使人们回想起老式WCF和LINQ to SQL的痛苦回忆。我花了很多时间来战斗两个框架。足够抽象,易于理解且易于自定义的框架确实是稀有鸟类。但是它们存在。
2014年

Answers:


21

框架确实很棘手。当框架过于“傲慢”时,即当它确实更喜欢一种特定的应用程序样式并且所有部分都旨在支持这种特定样式时,很容易出现问题。

例如,如果框架通过允许您仅添加一个组件,在某处添加登录模板并瞧瞧,就完全抽象了用户的身份验证过程,那么您将免费获得用户身份验证。这为您节省了许多重复的工作,使您不必担心Cookie,会话存储,密码哈希和其他问题。

当您意识到框架的身份验证代码的默认行为不是您所需要的时,问题就开始了。也许它没有遵循最新的最佳安全实践。也许您需要在流程中使用自定义钩子来触发某些操作,但是框架没有提供该钩子。也许您需要更改所设置的cookie的详细信息,但是该框架无法自定义此方法。

框架提供的抽象功能使您可以在几分钟之内(而不是最初的几天)向站点添加重要功能,但最终您可能不得不与该框架作斗争,以使其能够完成所需的工作,否则您将无论如何都必须重新从头开始重新设计功能,以满足您的需求。

请注意,这并不是说框架抽象不好。就是说,这始终是您需要牢记的一种可能性。一些框架明确针对此,它们提供了一种方法,可以非常快速地将某些东西作为原型,甚至针对非常有限的特定类型的应用的生产框架。其他框架更像是您可以使用的组件的松散集合,但它们仍然为您提供很大的灵活性,以便以后进行更改。

使用抽象时,您应该始终至少大致了解抽象的内容。如果您不了解Cookie和身份验证系统,那么从抽象开始就不是一个好主意。如果您确实了解您要尝试做的事情,而只需要已经做过的代码,而不必费力地编写自己的代码,那么抽象将节省大量时间。写得不好的抽象可能会在以后给您带来麻烦,所以这是一把双刃剑。


您还应该区分技术抽象和“业务规则”抽象。使用高级语言进行编程是您可能不希望错过的抽象(Python,PHP,C#,C,汇编程序; Less与CSS),而如果不这样做,“业务规则抽象”可能会很困难完全满足您的需求(一键式身份验证与手动编码Cookie)。

这是因为技术抽象很少“泄漏”,即,在用Python编写应用程序时,您几乎不必调试机器代码。业务规则抽象虽然在相同的技术级别上工作,但实际上只是“代码束”。你可能需要调试时设置cookie或者是在某些时候,这意味着你可以通过大量的第三方代码跳水创建的密码哈希值。


“如果您不了解cookie和身份验证系统,那么从抽象开始就不是一个好主意。”是的,但它可能仍然比您自己从头开始构建它要好。
2013年

@svick更快?是。更好?这值得商.。
Lunchmeat317

@ lunchmeat317我的意思是,如果某人不知道自己在做什么并且使用了框架,那么他很可能会犯一些错误。但是,如果他自己编写所有代码,则几乎肯定会犯错。
svick

2
同意。“您使用库,但框架使用您”是一个很好的报价。我们需要更多可重用的库和更少的多合一框架。
gbjbaanb

1
@gbjbaanb非常同意。尤其是因为“一切皆有可能”的框架很少具有最高的代码质量。同类最佳的库通常比通用框架的实现要好得多。
2013年

29

在我看来,您误解了抽象和代码重用。

整个软件开发行业都建立在抽象之上。仅仅因为不使用它们,即避免使用框架,库和非内部编写的一般代码,就会使制作一款软件所需的成本增加数十万甚至更多。

就像您不会从头开始创建大型喷气式飞机一样,如果不使用多年建造其他飞机时积累的任何工程知识,您也不会从头开始编写业务软件。

首先,确实可以通过使用PHP或Ruby来实现这一点,您已经拥有大量的抽象了,是吗?最明显的是:

  1. 操作系统,编程语言和编译器提供了对汇编器和硬件的巨大抽象,

  2. Web服务器提供套接字,故障转移,HTTP协议等的抽象,

  3. SQL提供了关于如何将数据存储在永久性存储支持上以及如何保存在内存中以加快访问速度的抽象,从而确保ACID,镜像等。

您可能总是尝试创建Web应用程序,而不使用操作系统,Web服务器,数据库或高级编程语言。你很快就会发现,你花了几年时间重新发明轮子,即重新创建你的编程语言,你的 Web服务器和您的数据库,因为它们的质量会从我们实际使用的产品的质量远。

框架与此没有什么不同。您可以执行他们的操作。只是您将浪费时间来重做相同的功能,不同之处在于那些框架会做得更好,而且经常会比您的框架更好地测试和记录其代码。

以电子商务网站的购物车为例。您可以发明自己的产品并花费数周的时间来开发它,也可以采用由一群人在框架内开发多年的产品。预计他们的程序将受到测试,这还不包括以下事实:几年后,这些开发人员发现并修补了开发自己的购物车时无法想象的大量错误。

您可能会回答说,他们的情况更为复杂,因为它有更多的用例。例如,当您的网站上没有折扣并且购物车中不需要此功能时,他们的折扣应该处理。好吧,您没有被迫使用此功能,并且它不会降低您的Web应用程序的性能。

当开发自己的购物车而不是使用现有的购物车真的要容易得多时,您可能会遇到一个非常基本的情况。同样,如果您的应用唯一需要存储的是数字列表,仅此而已,那么您就不需要数据库:简单的文本填充就足够了。在这种情况下,请不要过度设计您的应用程序:简单的场景需要简单的解决方案。

另一个因素是代码的可读性。想象您已经创建了一个电子商务网站。后来,您离开了项目,另一个开发人员应该维护它。

  • 如果您使用了框架提供的购物车,您的同事会放心的:他必须维护一小段代码,该代码依赖于可靠的,有大量文档记录的框架。甚至更好:这个开发人员可能已经习惯了使用这个框架并且对此很熟悉。如果没有,他可以在Stack Overflow上提问:可以肯定的是,有人已经使用了该框架。

  • 如果您有自己的购物车,那么您的同事将不得不维护一些自定义代码,甚至可能没有记录,而无法在任何地方获得帮助。

通过使用框架,您依赖于以下代码:

  • 由经验丰富的开发人员撰写,

  • 经常成对审核,

  • 单元测试

  • 广泛记录

  • 数以千计的开发人员使用了多年,

  • 通常受到支持,因此您可以报告错误并查看其实际修复情况,

  • 许多开发人员都知道这一点,他们知道可能的警告和问题,并可以在Stack Overflow之类的网站上提供帮助。

  • 现在为您免费提供。


3
抱歉,但这不能回答问题。按照我的解释方式,这个问题是关于何时有太多抽象及其所引起的问题,而不是抽象和框架是否有帮助。OP似乎已经了解到它们可能有用。但是,糟糕的抽象可能会带来痛苦和局限性,而好的抽象则可能会有所帮助和解放。

3
@MattFenwick-对我来说,OP表示如果您完全使用这些框架,则抽象程度过高,会导致更多问题,那么它们值得。当然问题是不好的抽象不好吗?
JeffO

3

我同意-大多数框架都变得肿独裁。他们承诺自由,但您最终陷入奴役状态。因此,将框架视为一种工具-最好的工具就是远离您使用的工具。如果使用PHP,我建议您检查Codeigniter框架,因为它在约定和自由之间保持了很好的平衡,并拥有一个强大的社区。对于使用电子商务购物车示例的发布者,我希望我能同意你的看法。但在查看了许多电子商务解决方案的代码(并设计了一些解决方案)后,我将不同意您的示例。


2

嗯,我们从事很多工作的LedgerSMB的一个方面是我们的框架方法。但是,这种抽象有两个基本问题。这些是:

  1. 依赖爆炸,以及

  2. 错误的抽象

第一个实际上比重新发明轮子的替代方法要好。第二个是一个很难贴上标签的标签,因为它可能来自定义不明确的问题案例,或者更经常地来自人们使用了超出其预期用途的东西。

让我们以ORM为例。我避免使用ORM,因为在很多情况下,数据库最终都是为应用程序的对象模型设计的,因为充其量它们是泄漏的抽象层。不一定是这种情况。我遇到过一些开发人员,他们在使用ORM时设法保留了良好的数据库设计和良好的应用程序,但是他们诉诸于orm炒作所说的不需要的很多事情,例如将db的关系API封装在可更新视图之后。

当然,主要的问题是代码的自动化程度越高,尤其是在代码也不透明的情况下,更难发现问题所在。这是@jhewlett在上面所做的关于ORM的观点(请参阅/software//a/190807/63722)。

良好的并行性可能是先进的航空电子设备,作为飞机驾驶的框架。这些经过高度工程设计以确保可靠性,并且是提高飞行安全性的一个因素。但是,正如IEEE Spectrum上的许多文章所指出的那样,这是出于从自动化角度认为可接受的范围之外的错误中恢复错误的代价。调试也是如此。在程序中调试SQL代码是一回事。调试程序的一部分,编写要供程序使用的SQL代码是完全不同的事情。

我们从头开始编写LedgerSMB框架,因为在开始的时候,还没有真正好的框架能够满足我们的要求。实际上,这是我非常满意的一件事,并且该项目的新开发人员认为,这使应用程序的自定义变得非常简单。(实际上,我们将SQL代码生成保持在最低限度,而是专注于手写的用户定义函数,这意味着sql编写的部分是很薄的胶水)。是的,它在某些地方提供了很多抽象,这超出了某些程序员所能接受的范围(特别是“将对象属性映射到该存储过程中的参数”使我们有时会被压倒)。但是,我们尝试使所有内容保持简单和一致,以便直接确定出了什么问题。效果很好。

最后,“太多”是有点主观的,但在客观层面上,它也取决于您在做什么。如果您确实在执行框架的设计工作,那么设计良好的框架将提供理想的抽象量。如果您正在做一些不太合适的事情,那么抽象将变得既太多又太多。


2

是的,它们很有用。它们为您提供了许多其他经验丰富的开发人员的工作成果,它们可以解决您需要解决的问题,并具有经过测试的附加好处,修复了许多错误,并提供了您不必担心的棘手问题的解决方案通过使用框架自己。

他们会be肿过度杀伤力吗?当然。这一切都取决于您需要什么,以及框架带来的好处。如果您有一个简单的Web应用程序,那么Rails可能对您来说太过强大了,您应该考虑使用Sinatra这样更简单的解决方案。

所有框架肯定都有学习曲线,并且为您节省了更多的工作,这变得更加陡峭。但是,学习框架意味着您已经节省了时间,并且可以在下一个项目中利用所有这些知识,而无需第二次从头开始重写应用程序。

但是,您说的是,我只是从旧项目中复制代码,就可以将其用作新项目的起点!我只是改变不同之处,也许使我的一些对象/功能更通用,并想出一种更好的方法来解决那段棘手的代码!恭喜,您已经创建了一个框架。再执行数千次,您将获得Django,Rails或Zend之类的东西。


1

框架通常会提高生产力(可能经过轻微的学习曲线之后),但通常需要权衡取舍。例如,在某些情况下,您以降低性能为代价提高了程序员的生产力。

考虑对象关系映射器(ORM)。它们很棒,因为它们为您处理了许多繁琐的映射代码。他们甚至可以为您创建对象。但是,在抽象化SQL时,要推理性能并优化瓶颈要困难得多。

如果您要构建的应用程序没有大量数据或复杂的查询,那么性能可能就不是您的问题。确实,程序员的时间是许多项目的瓶颈,而框架,库和高级语言有助于缓解这种情况。


1

我同意“您使用库,但是框架使用您”。这是一种非常整洁的表达方式。我不同意,一旦您开始重复使用代码,便开始构建框架,因为通常不需要做很多事情,只需快速复制并粘贴即可再次使用代码-这就是您正在建立的图书馆;无需为将代码带入网站或应用程序而感到奇怪。

对我来说,关键点在于,我必须从资源中获取更多资源,而这不仅仅是我需要投资的资源。或者,从另一个角度讲,我想说的是,只要框架的需求大于可用的奖励,就不会出现所有优势。所以是“是的!请!谢谢!所有那些资产将直线下降并在我自己的html / CSS / PHP和SQL中根据需要运行的资产。

我发现无法理解的一件事是,据说框架使维护更容易了吗?如果相互作用的零件的复杂网格无法按预期执行,那么您最好了解有关该框架的所有知识。或者准备好大量输入新语法。


0

有人说这是好莱坞框架原则:“不要打电话给我们,我们会打电话给您”。相反,无论何时使用库,您的代码都会调用库,而不是相反。

如您所见,重要的是谁在控制中-即,控制流的控制。谁决定哪个语句在哪个语句之后运行?

有赞成和反对的论据,每当我看到这种无休止的讨论时,我倾向于认为这一定是一个品味问题,而不是一个客观可决定的问题。否则,将已经决定。

在我看来,您是否喜欢使用框架或库可以说明您是哪种类型的开发人员,而不是这两种方法中的一种是否优越并且最终会占上风。

如果您喜欢框架,则希望交换自由以换取安全性:您可能更务实,并且您倾向于信任他人来正确地完成他们的工作。如果您更喜欢图书馆,那么您宁愿将安全换来自由:您可能更像是理想主义者,并且质疑他人的观点和主张。

我认为决定像前者或后者更好是明智的。

回答您的问题:框架是否放置了太多抽象?这取决于您是谁,尤其取决于您对基本原则的满意程度。

...

更具体地说,如果您不喜欢Django之类的框架,请搜索Flask之类的“微框架” :)

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.