为什么要远离对日外包

by Niklas Schöllhorn

由NiklasSchöllhorn

远离魔法-或:为什么我不想再使用Laravel (Moving away from magic — or: why I don’t want to use Laravel anymore)

It is time for a change in the tools that I use. And I’ll tell you why!

现在该改变我使用的工具了。 我会告诉你为什么!

First of all, I want to make sure that you know about my intentions. I am not trying to rant about Laravel or why other frameworks might be better.

首先,我想确保您了解我的意图。 我不是要抱怨Laravel或为什么其他框架可能会更好。

This article is very subjective. I’ll give you my thoughts and try to get you to rethink your framework choices as well. And when you stick with Laravel after reassessing, that’s fine. I have no intention to convert people away from Laravel to other frameworks or languages. But it is important to look closer and to make sure you know what you are using and why you are using it.

本文非常主观。 我会给您我的想法,并尝试让您重新考虑您的框架选择。 当您在重新评估后坚持使用Laravel时,就可以了。 我无意将人们从Laravel转向其他框架或语言。 但重要的是要靠近并确保您知道自己在使用什么以及为什么使用它。

介绍 (Intro)

I’ve worked with Laravel for about 2 years now. I always enjoyed how easy it was to spin up an application and get going in minutes. It provides so many useful tools out of the box. The console commands support you in every aspect during coding. They generate classes, scaffolding for authentication and much more.

我已经与Laravel合作了大约2年。 我一直很喜欢启动一个应用程序并在几分钟之内完成它是多么容易。 它提供了许多开箱即用的有用工具。 在编码过程中,控制台命令在各个方面都为您提供支持。 它们生成类,用于身份验证的脚手架等。

But the deeper you go and the bigger the projects become, the more complicated the development with Laravel will get. Or, let me rephrase it: the better other tools will do the job. I’m not even saying it’s only Laravel’s fault. It’s also partly due to PHP not being very well designed.

但是您越深入,项目越大,Laravel的开发就会越复杂。 或者,让我改一下:其他更好的工具可以胜任这项工作。 我什至不说这只是Laravel的错。 这也部分是由于PHP的设计欠佳。

Now, let’s start!

现在,让我们开始吧!

口才ORM (Eloquent ORM)

If you’ve already worked with Laravel, you surely know about Eloquent. It’s the ORM that’s shipped with a default installation. It comes with a lot of neat features. But its design makes your application needlessly complex and prevents the IDE from correctly analyzing your code.

如果您已经与Laravel合作,那么您肯定知道Eloquent。 默认安装附带的是ORM。 它具有许多简洁的功能。 但是其设计使您的应用程序不必要地复杂,并阻止IDE正确分析您的代码。

This is partly due to the Active Record ORM pattern that’s being used and partly due to the fact that Eloquent wants to save the developer from having to write more code. To do that, it lets the developer stuff a lot into the model that doesn’t belong there.

这部分是由于使用了Active Record ORM模式,另一部分是由于Eloquent希望避免开发人员不得不编写更多代码。 为此,它使开发人员可以将不属于该模型的模型塞入很多模型中。

Sounds like good intentions, but I started to dislike this more and more.

听起来像是个好主意,但我开始越来越不喜欢这个。

Let’s have a look at an example:

让我们看一个例子:

The first thing you see is that there are no properties on the model. This seems irrelevant but for me, it makes quite a difference. Everything is injected “magically” into the class by reading the table metadata. Of course, your IDE does not understand that without help. And you get no chance to name your properties differently from your columns.

您看到的第一件事是模型上没有属性 。 这似乎无关紧要,但对我而言,却有很大的不同。 通过读取表元数据,将所有内容“神奇地”注入到类中。 当然,如果没有帮助,您的IDE将无法理解。 而且,您没有机会以不同于列的名称来命名属性。

Now check out the scope method. For Laravel users, it’s pretty clear what it does. If you call this method, it scopes the underlying SQL query by adding the given WHERE clause.

现在检查范围方法。 对于Laravel用户而言,它的作用非常明显。 如果调用此方法,则它将通过添加给定的WHERE子句来限定基础SQL查询的范围。

You can see, it is not static. That would mean that this method operates on a specific object of the class. But in this case, it does not. A scope is called on a query builder. It has nothing to do with the model object itself. I’ll explain that after you see how you usually call those scopes:

您可以看到,它不是静态的。 这意味着该方法对类的特定对象进行操作。 但是在这种情况下, 它不是 。 在查询生成器上调用范围。 它与模型对象本身无关 。 在您了解通常如何调用这些范围之后,我将进行说明:

You’re calling a static method popular() that nobody ever defined. But since Laravel defines a __call() and __callStatic() method, it gets handled through them. Those methods forward the call to a query builder.

您正在调用没有人定义的静态方法popular() 。 但是由于Laravel定义了__call()__callStatic()方法,因此可以通过它们进行处理。 这些方法将调用转发给查询构建器。

This is not only something that your IDE doesn’t understand. It makes refactoring harder, might confuse new developers, and static analysis gets harder as well.

这不仅是您的IDE无法理解的。 它使重构更加困难,可能使新开发人员感到困惑,并且静态分析也变得更加困难。

In addition, when putting such methods on your model, you are violating the S of SOLID. In case you are not familiar with that, SOLID is an acronym that stands for:

此外,将此类方法应用于模型时,将违反SOLID的S。 如果您不熟悉它,SOLID是一个缩写,代表:

  • Single Responsibility Principle

    小号英格尔责任原则

  • Open/Closed Principle

    Ø笔/封闭原则

  • Liskov Subsitution Principle

    大号 iskov Subsitution原理

  • Interface Segregation Principle

    覆盖整个院落分离原则

  • Dependency Inversion Principle

    d ependency倒置原则

When you use Eloquent, your models have multiple responsibilities. It holds the data from your database, which is what models usually do, but it also has filtering logic, maybe sorting and even more in it. You don’t want that.

使用Eloquent时,您的模型有多个职责。 它保存着数据库中的数据,这通常是模型所要做的,但是它也具有过滤逻辑,也许还有排序逻辑。 你不要那样

全球帮手 (Global Helpers)

Laravel comes with quite a few global helper functions. They seem very handy and yes, they are handy.

Laravel具有很多全局帮助器功能。 它们似乎非常方便,是的,它们非常方便。

You just have to know that you sacrifice your independence for that handiness and your global namespace gets polluted. It rarely leads to conflicts, but avoiding that altogether should be preferred.

您只需要知道您会为此方便而牺牲自己的独立性,并且全局名称空间会受到污染。 它很少导致冲突,但是应该完全避免这种冲突。

Let’s look at a few examples. Here’s a list of three helper methods that we have but don’t need since there are better alternatives:

让我们看几个例子。 这是我们有但不需要的三个辅助方法的列表,因为有更好的选择:

  • app_path() — why? If you need the path of the app, ask the app object. You get it by type hinting.

    app_path() -为什么? 如果您需要应用程序的路径,请询问应用程序对象。 您可以通过类型提示获得它。

  • app() — huh? We don’t need this method. We can inject the app instance!

    app() —是吗? 我们不需要这种方法。 我们可以注入该应用实例!

  • collect() — This creates a new instance of the Collection class. We can just new an object up by ourselves.

    collect() —这将创建Collection类的新实例。 我们可以自己新建一个对象。

One more concrete example:

一个更具体的例子:

We are using Laravel’s global request() helper to retrieve the POST data and put it in our model as the attributes.

我们正在使用Laravel的全局request()帮助器来检索POST数据,并将其作为属性放入我们的模型中。

Instead of using the global helper, we could type hint a Request object as a parameter in the controller method. The dispatcher in Laravel knows how to provide us with the needed object. It will call our method with it and we don’t have to call a helper.

代替使用全局帮助器,我们可以在controller方法中键入hint一个Request对象作为参数。 Laravel中的调度员知道如何为我们提供所需的对象。 它将使用它来调用我们的方法,而不必调用一个助手。

And we can take this a step further to decouple even more. Laravel is PSR-7 compliant. So, instead of type hinting the Request object, you could also type hint ServerRequestInterface. That allows you to replace the whole framework with anything that’s PSR-7 compliant. Everything in this method will continue to work. This would fail if you’re still be using the helper methods. The new framework wouldn’t come with the helper method and therefore, you’d have to rewrite that part of your code.

而且,我们可以采取进一步的措施来进一步分离。 Laravel符合PSR-7 。 因此,除了键入提示Request对象的类型外,您还可以键入hint ServerRequestInterface 。 这样一来,您就可以使用与PSR-7兼容的任何产品来替换整个框架。 此方法中的所有内容将继续起作用。 如果您仍在使用辅助方法,则此操作将失败。 新框架不会附带helper方法,因此,您必须重写代码的这一部分。

You rarely switch the whole framework, but there are people who do. And even if you might never switch, it is still important for interoperability. Being able to inject dependencies and have a concise data flow instead of resolving and requesting dependencies and data inside out is the way to go. It makes testing, refactoring, and nearly everything easier when you get a grip of it.

您很少切换整个框架,但是有些人这样做。 即使可能永远都不会切换,它对于互操作性仍然很重要。 能够注入依赖关系并拥有简洁的数据流,而不是从头解决并请求依赖关系和数据是可行的方法。 当您掌握了它时,它将使测试,重构和几乎所有操作变得更加容易。

I was happy when I read that with Laravel 5.8 the string and array helpers get removed from the core and put into a separate package. This is a good first step. But the documentation should start to discourage usage of all helper functions.

当我读到Laravel 5.8时,我很高兴能将字符串和数组助手从核心中删除并放入一个单独的包中。 这是一个很好的第一步。 但是文档应该开始阻止所有助手功能的使用。

外墙 (Facades)

The arguments from the last part come into play here as well. Facades seem to be a nice tool to quickly access some methods that are not really static. But they tie you into the framework once again. You use them to manually resolve dependencies instead of instructing the environment to provide them.

最后一部分的论点也在这里起作用。 外观似乎是快速访问某些并非真正静态的方法的好工具。 但是它们再次将您束缚到框架中。 您可以使用它们来手动解决依赖关系,而不是指示环境提供依赖关系。

The same goes for the complexity by passing everything through the magic methods.

通过将所有内容都传递给魔术方法来解决复杂性问题。

Since we were talking about IDE support, I know some of you might direct me to the IDE helper package from barryvdh. You don’t need to. I already know this package. But why is it even needed? Because some design decisions in Laravel are just not good. There are frameworks where you don’t need that. Take Symfony for example. No need for IDE helper files, because it’s well designed and implemented.

自从我们谈论IDE支持以来,我知道你们当中有些人可能会引导我进入barryvdh的IDE帮助程序包 。 不用了 我已经知道这个包了。 但是,为什么甚至需要它呢? 因为Laravel中的某些设计决策并不好。 有不需要的框架。 以Symfony为例。 不需要IDE帮助程序文件,因为它经过精心设计和实施。

Instead of facades, we could use dependency injection again as we did in the previous example. We’d have a real object and could call real methods on it. Much better.

可以像上一个示例一样再次使用依赖项注入来代替Facade。 我们将有一个真实的对象,并可以在其上调用真实的方法。 好多了。

I will once again give you an example:

我将再举一个例子:

We could easily clean this up. Let’s tell Laravel to inject a ResponseFactory and pass us the current request:

我们可以轻松清理它。 让我们告诉Laravel注入ResponseFactory并将当前请求传递给我们:

We have now successfully eliminated the use of facades from our controller. The code still looks clean and compact, if not even better than before. And since our controllers always extend the general Controller class, we could take everything a step further by moving the response factory to that parent class. We need it in all other controller classes anyways.

现在,我们已成功从控制器中消除了外墙的使用。 该代码看起来仍然干净整洁,即使没有比以前更好。 而且由于我们的控制器总是扩展通用的Controller类,因此我们可以通过将响应工厂移到该父类来使一切更进一步。 无论如何,我们在所有其他控制器类中都需要它。

I heard that some people provide “too many constructor parameters” as an argument against injecting everything. But I don’t agree with that. It’s only hiding the dependencies and thus complexity in the first place. If you don’t like having 10 to 20 arguments in your constructor, you are right.

我听说有人提供“太多构造函数参数”作为反对注入所有内容的论据。 但是我不同意。 首先,它只是隐藏了依赖关系,因此也隐藏了复杂性。 如果您不喜欢在构造函数中使用10到20个参数,那么您是对的。

The solution isn’t magic though. Needing that many dependencies in a single class means that this class most likely has too many responsibilities. Instead of hiding that complexity, refactor that class. Split it up into new ones and improve on your application architecture.

解决方案并不是魔术。 在单个类中需要许多依赖关系意味着该类很可能承担太多职责。 不必隐藏那种复杂性,而是重构该类。 将其拆分为新的并改进您的应用程序体系结构。

Fun fact: there’s a real design pattern called “facade pattern”, introduced in the Gang of Four’s book. But it has a completely different meaning. Laravel’s facades are essentially static service locators. The naming just doesn’t convey that. Same naming for different things also makes discussions about architecture in projects harder, because the other party might expect something completely different behind that name.

有趣的事实:《四人帮》(Gang of Four)的书中介绍了一种称为“外观模式”的真实设计模式。 但是它具有完全不同的含义。 Laravel的外墙本质上是静态服务定位器 。 命名并不能传达这一点。 对不同事物的相同命名也使对项目中的体系结构的讨论更加困难,因为另一方可能期望在该名称后面有完全不同的事物。

结论 (Conclusion)

Let’s come to an end. I might write a follow-up soon about which technologies I prefer to use nowadays. But for the moment, let me sum up what we’ve learned:

让我们结束吧。 我可能会很快就我现在喜欢使用哪些技术写一篇后续文章。 但是现在,让我总结一下我们学到的东西:

Laravel’s approach to making everything as easy as possible is good. But it’s hard to get along when your apps become more advanced. I prefer awesome IDE support, stronger typing, real objects, and good engineering. I might even go back to Laravel when I want to write a smaller app.

Laravel使一切变得尽可能简单的方法是好的。 但是,当您的应用程序变得更高级时,很难相处。 我更喜欢出色的IDE支持,更强的键入,真实的对象以及良好的工程设计。 当我想编写一个较小的应用程序时,我什至可以回到Laravel。

A lot of my points are not only Laravel’s fault. I could swap the parts I don’t like, for example the ORM. But instead, I’ll just switch the toolkit, where the defaults fit my needs better. I see no point in using a framework where I have to spend more time in avoiding traps it sets for bad engineering than in developing my app. Other frameworks and tools come with better designed defaults and less magic.

我的很多观点不仅是Laravel的错。 我可以交换我不喜欢的部分,例如ORM。 但是,我只需要切换工具箱即可,默认设置更适合我的需求。 我发现使用框架比开发应用程序要花更多的时间,在框架上花很多时间来避免因不良工程而造成的陷阱是没有意义的。 其他框架和工具具有更好的默认设计和更少的魔力。

So for now, I’ll say goodbye to Laravel.

所以现在,我将告别Laravel。

Thank you for your time. I’d appreciate a nice discussion in the comments and I am of course open for your questions and suggestions.

感谢您的时间。 非常感谢您在评论中进行了精彩的讨论,当然欢迎您提出问题和建议。

P.S.: Special thanks to Marco Pivetta for proof reading and additional input!

PS:特别感谢Marco Pivetta的校对和其他投入!

Edit March 1st, 2019:Since my article was posted on Reddit, I have created a Reddit account to answer a few comments. My account is not the one the article was posted from, but this one: https://reddit.com/u/nschoellhorn

编辑2019年3月1日:自从我的文章发布在Reddit上以来,我创建了一个Reddit帐户来回答一些评论。 我的帐户不是发布该文章的帐户,而是这个帐户: https : //reddit.com/u/nschoellhorn

Edit March 13th, 2019:If you read this far, you can as well check out my Twitter profile. Thank you for your continued interest in this topic! I am always open to productive discussions, so please feel free to get in contact, either here or on Twitter.

编辑2019年3月13日:如果您已阅读本文,则还可以查看我的Twitter个人资料 。 感谢您一直以来对该主题的关注! 我总是愿意进行富有成效的讨论,因此,请随时在此处或在Twitter上与我们联系。

翻译自: https://www.freecodecamp.org/news/moving-away-from-magic-or-why-i-dont-want-to-use-laravel-anymore-2ce098c979bd/

为什么要远离对日外包

为什么要远离对日外包_远离魔法-或:为什么我不想再使用Laravel相关推荐

  1. 预成大器,远离对日外包

    我的这篇文章每一个字都是三年血泪的精华,希望不要落下任何一个字! 程序员,是一份职业.真正的名字应该叫软件工程师,是真正的技术职业. 程序员,是一个行业的定位,她包含在了"软件工程" ...

  2. 隔行如隔山 -- 乱弹技术,经济,对日外包

    晚上和一个国内的朋友聊天,他做.net做了好多年. 不聊不知道,一聊吓一跳,原来.net里面水那么深,以前一直觉得是垃圾来着. 原来.net里面也有各种各样的框架,也有内存调优,也有DI,也有脚本化编 ...

  3. 对日外包十日谈 之 我所了解的对日外包企业

    对日外包十日谈 之 我所了解的对日外包企业 蒋彪 2010-5-23 于上海浦东 1.   前言 关于对日外包,我其实本来已经不想说些什么了.因为,我已经离开了对日外包行业. 这个行业的是与非,正确与 ...

  4. 干了十年对日外包的菜鸟的简单告白

    干了快十年的对日软件外包了,突然发现自己什么都不会了.其实原来也有这样的短暂的困惑 但是没有好好的静下来去想一想.今天突然想是不是应该做出一些改变了 哪怕是一点点 并且坚持下去. 呵呵 就从今天开始吧 ...

  5. 谈谈关于对日外包开发

    在论坛上发现已经有了一个规律,就是只要谁说自己是做对日外包开发的,或者提问说对日外包好不好,有没有前途,马上就会招来一大片嘘声,有些人干脆破口大骂.我自己做对日外包做了2年多,也想来稍微说几句. 首先 ...

  6. 对日外包 简述 解惑 扫盲

    一直想写一篇关于对日外包方面的东西.今天百度了一下,发现百度知道上写的太过于简单,并且有些地方描述的不是很恰当. 引用如下: 对日外包:就是日本方面把软件开发的活承包给中国公司作,主要利用中国的高技术 ...

  7. 我看对日外包开发就是不错

    在论坛上发现已经有了一个规律,就是只要谁说自己是做对日外包开发的,或者提问说对日外包好不好,有没有前途,马上就会招来一大片嘘声,有些人干脆破口大骂.我自己做对日外包做了2年多,也想来稍微说几句. 首先 ...

  8. 初入对日外包(对于对日外包资料的整理)

    对于外包来说主要有三种开式,第一种就是像大连这种以软件外包为主的城市,整个城市的主要软件产业就是外包,目标是超过印度的班加罗尔.第二种形式是大公司将软件项目外包给小公司去做.(本质上与第一种形式也是一 ...

  9. java语言的诞生日是_【logofree】JAVA语言诞生日百度LOGO在线制作

    Java语言诞生日百度LOGO创意说明 5月23日是JAVA语言诞生的日子.我们制作了 一款有趣的互动来纪念这一天.LOGO是整个游戏的入口,也是JAVA之父高斯林的办公桌.复古的电脑以及电话机体现了 ...

最新文章

  1. 了解 GNU GPL/GNU LGPL/BSD/MIT/Apache协议
  2. Cortex-M3 异常中断向量表
  3. mysql 经纬度距离 自定义函数_mysql 经纬度计算距离 自定义函数
  4. 二进制除法\模2除法
  5. matlab识别图像,基于MATLAB神经网络图像识别的高识别率代码
  6. Git 的 4 个阶段的撤销更改
  7. 《像计算机科学家一样思考Python》pdf
  8. 6.1Python文件的操作(一)
  9. FluentValidation
  10. Google 开源 VHP 震动触觉平台,降低触觉设备开发难度
  11. [虚拟机]Windows server 2019 无法安装 .NET Frameword 3.5
  12. 计算机处理器性能排名,2019电脑cpu处理器性能排名:AMD 32核撕裂者遥遥领先(2)...
  13. ImportError: cannot import name ‘_validate_lengths‘解决方法
  14. Windows 2008 R2 标准版 ie提示 当前安全设置不允许下载该文件 解决办法
  15. Single-Domain Generalized Object Detection in Urban Scene via Cyclic-Disentangled Self-Distill阅读笔记
  16. Sql练习--查询有趣的电影
  17. 已解决RuntimeError: CUDA error: device-side assert triggered异常的正确解决方法,亲测有效!!!
  18. Dev c++无法新建项目解决方法
  19. 财会法规与职业道德【4】
  20. Unity3d游戏聊天匹配手机虚拟键盘

热门文章

  1. SpringBoot—jasypt加解密库的使用方法
  2. Map集合 java
  3. is 与 as 数据类型的操作 0108
  4. 作业 输出演练 1751
  5. mysql数据库引擎InnoDB和MyISAM
  6. 【ES6入门04】:数值扩展
  7. spring mvc 为什么这么多xml
  8. FutureV接口CallableV接口的使用
  9. 2017年预测:突破性创意工作站、物联网
  10. 机器学习是如何改善企业生产力的?(内附机器智能版图)