Aura: More Decoupled Than Symfony 2 and Zend Framework 2

By | December 11, 2012

The guys at PHPMagazin have posted a followup question about the Aura Project for PHP. Here is our original English conversation.


I’d like to follow up on the last point where we talked about other frameworks. I think that the second generations of symfony and Zend Framework have gone through a huge decoupling process. This becomes evident when you look at symfony2 components being used in Drupal 8 or web tutorials which show you mixed use of zend- and symfony components.

So I think we could elaborate further on that last bullet point we discussed. Does the above change your angle in this regard?

Not in this case. Being able to use Symfony2 components or ZF2 modules is not quite the distinction I am making. The distinction is that all Aura packages (with the exception of the Framework package) are completely independent, and have no cross-package dependencies, whereas at least some of the components from Symfony2 and ZF2 have dependency requirements.

By way of comparison, let’s examine something that ought to be relatively straightforward: input validation and filtering. We’ll start with ZF2, then move on to Symfony2, and end with Aura. In each case, we will try to download the package and run its tests; this should be a good indicator of whether or not the package can be used independently. We will discover that you can’t do it at all with ZF2, you can kind of do it with Symfony2, and that it’s trivially easy with Aura.

Zend Framework 2

Let’s start by downloading the ZF2 InputFilter package. It doesn’t appear to be available for download by itself — there is the main ZF2 repository at Github https://github.com/zendframework/zf2 but that’s the whole framework, not just the InputFilter.

OK then, we can at least use Composer to incorporate the InputFilter into a project. We will set up a Composer file per the ZF2 instructions and install the InputFilter package. Our composer.json file looks like this:

{
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.zendframework.com/"
        }
    ],
    "require" : {
        "zendframework/zend-inputfilter" : "2.0.*"
    }
}

After downloading Composer into the same directory, we run the installer, and this is what we see:

$ ./composer.phar install
Loading composer repositories with package information
Installing dependencies
  - Installing zendframework/zend-stdlib (2.0.5)
    Downloading: 100%

  - Installing zendframework/zend-servicemanager (2.0.5)
    Downloading: 100%

  - Installing zendframework/zend-filter (2.0.5)
    Downloading: 100%

  - Installing zendframework/zend-i18n (2.0.5)
    Downloading: 100%

  - Installing zendframework/zend-validator (2.0.5)
    Downloading: 100%

  - Installing zendframework/zend-inputfilter (2.0.5)
    Downloading: 100%

zendframework/zend-stdlib suggests installing pecl-weakref (Implementation of weak references for StdlibCallbackHandler)
zendframework/zend-servicemanager suggests installing zendframework/zend-di (ZendDi component)
zendframework/zend-filter suggests installing zendframework/zend-crypt (ZendCrypt component)
zendframework/zend-validator suggests installing zendframework/zend-db (ZendDb component)
zendframework/zend-validator suggests installing zendframework/zend-math (ZendMath component)
Writing lock file
Generating autoload files
$

In order to use input filtering from ZF2, six other packages are required, and a few others are suggested.

Now that we’ve installed it, where are the tests? They’re not provided with the Composer package, although I suppose they are available with the framework as a whole. It appears the Zend offering is not entirely self-contained.

(If we look closely, we see that InputFilter is composed of at least two other packages that might suit our needs, zend-filter and zend-validator. However, when you examine them, they’re not comparable to Aura.Filter and Symfony2 Validator.)

Symfony 2

Let’s do the same thing with Symfony. This time it is downloadable through Github: https://github.com/symfony/Validator

Let’s clone the package and run the tests.

$ git clone https://github.com/symfony/Validator.git
Cloning into Validator...
remote: Counting objects: 3459, done.
remote: Compressing objects: 100% (672/672), done.
remote: Total 3459 (delta 2708), reused 3451 (delta 2700)
Receiving objects: 100% (3459/3459), 621.73 KiB | 730 KiB/s, done.
Resolving deltas: 100% (2708/2708), done.
$ cd Validator/Tests/
$ phpunit
[phpunit fails]

It appears we can’t just download the package and run the tests. The README states we need to use Composer and install all the --dev dependencies, so we’ll do that. First we download Composer into the cloned repo, then:

$ ./composer.phar install --dev
Loading composer repositories with package information
Installing dependencies
Nothing to install or update
Loading composer repositories with package information
Installing dev dependencies
  - Installing symfony/yaml (dev-master bed4fdd)
    Cloning bed4fddc24392513e01b32a78d600b1272ed9a6c

  - Installing symfony/locale (dev-master 2dceded)
    Cloning 2dcededb060dfb6289ad8bb3f2a7a4e00929c4dc

  - Installing symfony/http-foundation (dev-master 067c310)
    Cloning 067c310fe4d0691a24adc97f39500233a58e42cb

Writing lock file
Generating autoload files

Interesting: in order for the tests to run we need three other packages. It looks to me like there are cross-package dependencies. Examining the codebase reveals this to be true:

  • If you want to use the YAML loader included with the Validator, you need that YAML package after all.

  • If you want to validate against anything related to locales or languages, you need the Locale package. For example, the LangaugeValidator.php file makes a static call to SymfonyComponentLocaleLocale::getLanguages().

  • If you want to use Annotations with the Validator, it looks like you need Doctrine, which isn’t a part of the Symfony vendor hierarchy at all. Goodness knows what that will require.

Anyway, now we can run the tests; I have omitted the test progress output.

$ phpunit
PHPUnit 3.7.9 by Sebastian Bergmann.
...
Time: 8 seconds, Memory: 17.75Mb

OK, but incomplete or skipped tests!
Tests: 987, Assertions: 1091, Skipped: 12.
$

12 tests have to be skipped because of missing dependencies. When we run phpunit --verbose we discover that:

  • 3 tests are skipped are because APC is not loaded for the command line, which is not such a big deal;

  • 6 are skipped because “The Doctrine Common library is not available”;

  • 3 are skipped because “Annotations is required for this test”.

As with the ZF2 InputFilter component, it looks like the Symfony2 Validator component is not entirely self-contained. It has external dependencies that must be fulfilled in order for it to be fully useful.

Aura.Filter

Finally, we have the Aura.Filter package. It is downloadable through Github at https://github.com/auraphp/Aura.Filter. Let’s try to clone it and run the tests; I have again omitted the test progress output.

$ git clone git@github.com:auraphp/Aura.Filter.git
Cloning into Aura.Filter...
remote: Counting objects: 1105, done.
remote: Compressing objects: 100% (373/373), done.
remote: Total 1105 (delta 631), reused 1076 (delta 602)
Receiving objects: 100% (1105/1105), 725.94 KiB | 606 KiB/s, done.
Resolving deltas: 100% (631/631), done.
$ cd Aura.Filter/tests/
$ phpunit
PHPUnit 3.7.9 by Sebastian Bergmann.

Configuration read from /Users/pmjones/Aura.Filter/tests/phpunit.xml
...
Time: 4 seconds, Memory: 9.75Mb

OK (1009 tests, 1443 assertions)
$

No external dependencies, and nothing extra is needed for the tests to run. The package is completely self-contained, independent, and decoupled. Now compare the memory use and time taken to that of Symfony2: about half the memory used, and about half the time taken, to complete about 30% more assertions in the tests. (Incidentally, we have 100% test coverage of the source classes, but I don’t know how that compares to Symfony and Zend.)

Conclusion

None of the above is to meant to say that Zend Framework or Symfony2 are poorly architected, not useful, or any other negative thing. They are good projects, and the components appear to be good too.

The only thing I am saying is that their offerings of separate components are not always very well decoupled. This is because they started with a framework and tried to extract pieces from it. (To be fair, some components from both of those projects really are dependency-free, but not all of them.)

But in Aura, with its “libraries first” approach, every package is truly decoupled, independent, and self-contained, with zero cross-package dependencies. That is the major difference I want to emphasize.

45 thoughts on “Aura: More Decoupled Than Symfony 2 and Zend Framework 2

  1. Lukas

    I am having a bit of trouble following your argument here. I see your argument for fully decoupled components, but I dont see why components should not offer integration with other components, which is why the tests may have broader requirements than the actual component. If you know that your users are likely to be using those other components it makes absolute sense and imho doesnt hurt the decoupledness.

    F.e. Symfony2 Routing has a RequestContext and the Routing component has a method to create a RequestContext from an HttpFoundation Request. As a result when testing the Routing component there is a test that requires HttpFoundation to test if this conversion method does its job.

    Now in places where we felt that this would add too much code to the component we have the concept of Bridges in Symfony. For example the twig templates for the Form component are in the TwigBridge.

    Reply
  2. SeKrebs

    Don’t get it … Whats the matter in “It has dependencies”? And especially whats the matter in “It has dependencies to _foreign_ packages”?!? A “well decoupled” package doesn’t necessarily mean, that they must be “_completely decoupled” (in my understanding).

    Well, with this in mind: It’s nice, but what is the win?

    ( besides:
    Do you really compare the package requirements for dev-environments?
    – Do you really comparing the runtime and memory usage of unit tests?!?
    )

    Reply
  3. Dave Marshall

    Hi Paul

    Perhaps a follow up blog post as to why you think this is a good thing?

    Also, you don’t really mention if the Aura package has feature parity with the Zend And Symfony offerings. For example, if Aura.Filter can’t load it’s configuration from a Yaml file or from annotations, perhaps that’s not a very fair comparison to draw?

    Disclaimer: I’ve been using the symfony components for quite a while and you could consider me a Symfony convert

    Reply
  4. Matthew Weier O'Phinney

    Paul — a couple of points need a little bit of attention.

    What I’ve seen you do in Aura is that you provide bridge interfaces whenever there is a potential dependency on another component; this allows for the component to be decoupled — but it also means that the component may not be fully useful without (a) installing the other component(s), and/or (b) coding something yourself to fulfill the various interfaces. This is fine — but it means more work for the developer.

    With ZF2, we also provide a ton of interfaces. However, instead of providing bridge interfaces, we decided instead that if the interface already existed elsewhere, we’d add a dependency. This prevented us from duplicating effort (thus adhering to the DRY principle), at the expense of having dependencies. Since tools like Composer and Pyrus can manage this latter, we felt it was a reasonable tradeoff.

    In the case of InputFilter, I’d argue that we abstracted one step further than Aura or Symfony — we recognized that data validation and data normalization are often two separate processes, and each deserves its own component. The InputFilter comsumes the two functionalities in order to provide a robust component around validation and normalization of sets of data.

    We also made the decision not to ship tests with individual component packages. Practically speaking, the majority of users don’t execute the tests, nor really ever look at them. On the flip side, they _do_ want smaller package sizes (I never quite understood this argument, but I won’t argue with the numbers of people who felt that way). Not shipping tests made sense. For those that want them, the source is available on github.

    In reading back through your article and my response: I think a distinction needs to be made between abstraction and decoupling, both of which operate around the sphere of components. When we talk about decoupling, we should be talking about external dependencies. When we discuss abstract, we should be talking about the specific problem area a component addresses. A good abstract component does one thing, and one thing well — something I think all three frameworks achieve. Decoupling indicates the ability for a component to exist without dependencies — which may have both positive and negative connotations as I outlined above. While I *would* argue that decoupling is a differentiating factor of Aura, I wouldn’t necessarily argue that it means it is a *better* framework, or an *easier* framework; that will depend on the use cases a developer has, and how they can consume the component.

    Reply
    1. pmjones Post author

      Hey Matthew,

      You said: “I wouldn’t necessarily argue that it means it is a *better* framework, or an *easier* framework; that will depend on the use cases a developer has, and how they can consume the component.”

      I completely agree. The PHPMagazin guys asked what makes Aura “better”, and I amended their title to say merely “different.” ;-)

      Reply
  5. Nate Abele

    Matthew, to your point about end-user priorities (package size vs. included tests), I wouldn’t take that any way other than a sad reflection on the lack of focus on best practices in the PHP community.

    One thing I really appreciated about CPAN (okay, probably the only thing) was that installing a package without running the tests is Simply Not Done™. It’d be great if this was something Composer could do by default, though I realize the security implications of PHP not having something akin to a sandbox mode.

    Reply
  6. Matthew Weier O'Phinney

    Nate — We could definitely ship tests; composer certainly does not restrict this. However, in practice, it generally means installing additional libraries if you want to run the tests: e.g., phpunit (don’t assume it’s available!), some “suggested” dependencies so that optional features can be tested, etc. While you can do this with the “require-dev” key, that also means you need to use the “–dev” switch when installing. And currently, if you install a dev version of a ZF2 package, it clones the entire master or develop branch (based on the version you request), which gives you tests; so it’s certainly possible, and something you can request within your individual project quite simply.

    Reply
    1. pmjones Post author

      Matthew,

      You said, “And currently, if you install a dev version of a ZF2 package, it clones the entire master or develop branch (based on the version you request), which gives you tests …”

      Mea culpa: I did not see on Github where one can clone an individual ZF2 package. Can you point me to one?

      Reply
  7. Matthew Weier O'Phinney

    Paul — you can’t. If you have “minimum-stability” set to “dev”, then it will install the full ZF2 repo, and not the individual component (there’s syntax in Composer to allow one package to replace another, and we do that in this case). The individual packages are all contained in a single repository for now, but cannot be installed individually from that repo yet; the Composer devs are working on a solution to allow that in the future.

    Reply
    1. pmjones Post author

      Gotcha. I was worried I had misrepresented the downloadability of individual packages from Github.

      Reply
  8. Ralph Schindler

    Paul-

    As we’ve had this discussion in the past, I think for the most part we are on the same page. At the end of the day, it does really come down to how one approaches the DRY principle, and where that imaginary line is drawn in the sand with respect to how much code is worth not repeating.

    For example, array_merge_recursive() doesn’t always behave the way you’d expect when the key is an integer. So now, if you have 2 components that are sharing the same 8-10 lines of code that iterate an array and merge them, is it worth creating a new component that houses this algorithmically important functionality, exposing it as a dependency and depending on it. That is very much subjective, and at the end of the day, frameworks that are driven by a community process need to get community approval for deciding where that line is drawn in the sand. Thus the value of DRY/dependency vs. component isolation is very much a community decision, and tools like composer and pyrus are a factor when making those decisions.

    Personally, I like the unix philosophy where “do one thing and do it well” applies and the minimal “dependency”/expectation is the base system. In our case, the base system is the PHP runtime itself.

    On the matter of tests though, I firmly believe tests should not be shipped in component/library code that is intended purely for consumption. Perhaps there was a good reason to in the PECL days, or for CPAN code, but in today’s day and age of GitHub+Travis, development code and consumption of code should exist in two separate channels. The consumption channel should be driven primarily by ease of use (one click installer); whereas the development channel should exist in such a way that fosters conformity in development process. “Do the tests run and pass?” “I dunno, check the README.md for that little icon that says Travis.ci ran it and it passed.” Should the same developer that merely wants to consume the code really need to understand the ins/outs of PHPUnit and it’s mocking system? I think not. Besides, PHPUnit itself is a dependency for tests- you failed to mention that ;) And, some components might not use PHPUnit, they might use something entirely different- like phpt.

    Reply
  9. Nate Abele

    Hey Ralph, I see where you’re coming from, but your suggestion to “just check Travis” entirely misses the point: unless you’re running systems *identical* to Travis in both development and production (and even then), running tests before integrating or building a system *always* has value.

    I mean, half the point of CI and automated testing is not to rely on assumption, right? :-)

    Reply
  10. Hari K T

    Hey Ralph, Matthew,
    I strongly feel tests must reside in the package, and yes I wrote about it some months back Is there a design flaw for the Components or Packages made by Symfony2 and Zend Framework 2 http://harikt.com/any-design-flaw-for-components-packages-for-symfony2-zf2 where I saw a tweet from @Lukas.
    Yes @Fabien moved the tests to all components and I feel it was really the best move Symfony did, may be they have better ones than this.

    The good part when you keep standalone components is keep in a seprate repo ,let them fork and work on it. Seems like a bug running the package ? Let him write a test and fix the source run the whole tets…. ahh test in travis pass :) . Where on the master or develop. I am with the clone. Hell ? :) .

    And yes its not just you guys decision, with all respect, but may be the decision was wrong not to keep tests in the same repo.

    Reply
  11. Ralph Schindler

    Hari K T:
    The tests reside in the git repository where you’re suppose to issue a pull request against. The problem with testing environments is that they have a much larger set of requirements and “development knowledge” than that of the code you want to simply consume and use. Ensuring people go down the path of “contributing”, or at least read: https://github.com/zendframework/zf2/blob/master/CONTRIBUTING.md ensures that when they have problems as to “why won’t these tests run / what am I doing wrong / can someone help me / where do I get this phpunit command from?” a more experienced project developer can at least be sure they cloned the proper repository and the component to component wiring is handled correctly (we do it inside phpunits bootstrap script, also, having everything in a single repository ensure components are relative to one another, and loadable by a single autoloader).

    As for ZF, the canonical place for the components code is in the zf2 repository. We don’t have individual repositories for each component. Further, the concept of a package is strictly something built for release and consumption purposes, we don’t want/expect anyone to use a consumption phar or pyrus package to use to develop against and/or create patches for. Managing patches would be a nightmare (does that remind you of SVN days? ;)

    Nate:
    I am not suggesting that one should “just check travis”. What I am suggesting is that if you need more than to know that the tests run is a community supported environment, which Travis does a good job of setting up, then you should at least check out the tests in the full repository as all other contributors do. We simply don’t support running tests from release packages of single components.

    Reply
  12. Pingback: Aura: More Decoupled Than Symfony 2 and Zend Framework 2 | codegooroo

  13. Frank Fox

    so, let me see if i get that right, all Aura packages work with zero dependencies? does that mean that shared code is copied to each package?

    Reply
    1. pmjones Post author

      What shared code? ;-)

      In seriousness: it turns out that the amount of “shared code” that has to exist between these packages is almost nonexistent. If you like, you can review the packages yourself if you think that sounds unbelievable.

      Reply
  14. Drak

    I’m not entirely sure I see the point of this post. Seems to me like you are promoting NIH. The very concept that a decoupled component cant have dependencies means you have to invent everything yourself. It’s a step back into the dark ages. Suggesting a library is somehow deficient because it has dependencies on other components from the same vendor is frankly absurd. I agree it should be down to a minimum – Zend 1 being a good example of how it could get overly complex. Some of this however was down to there not being common interfaces, something hopefully we’ll solve with future PSRs.

    Furthermore, to suggest there is somehow more complexity to the user just because one library depends on another is also quite untrue given the advent of composer.

    Reply
  15. webmozart

    Paul,

    I’m disappointed by this blog post. If you want to promote Aura, please do so in a reasonable and fair way.

    There’s a distinction between required dependencies and optional, supported libraries. For example, the Symfony2 Validator *optionally* supports annotations, in which case you need DoctrineCommon (why should it reinvent annotation parsing?). You *can* use the Validator without any of these supported libraries.

    Obviously, the support for these libraries is tested, so for running the tests you also need the supported libraries (doh). I fail to see how this is bad.

    Last, please stop promoting NIH. With Composer, relying on other libraries that already solve a given problem is a *good* thing. Why should ZF2 copy the code of StdLib to all its components? The number of dependencies should be kept low, but there’s no reason to keep it at zero just for the sake of it.

    Bernhard

    Reply
  16. Amy Stephen

    In all honesty, I’m trying to understand the protest here. In all things, there are costs and benefits, pro’s and con’s. From my perspective, Paul has made a strong case that Aura is decoupled. He’s also demonstrated other examples that are not as decoupled. Seems like people might be projecting that further than is necessary since I don’t see any suggestion of anything beyond that singular architectural achievement.

    Disagree with Paul’s assertion in the comments that such a strategy does not lead to some duplication of code or function or that the methodology means some functionality be sacrificed. Of course, it does. That’s the ying and the yang of it – get one thing clean and another dirty – the cost, time,quality triangle – It’s math. It’s always a balancing act building software. Uncoupling is but one of many, many important factors.

    To the Symfony people. I am so turned on by Symfony2. I am using the HTTP foundation and class loader, recommend it to others. I love the engagement with other PHP projects. Thrilled to see the Drupal project taking hold.

    Having said that, please ease up a bit. It isn’t as appealing seeing repeated NIH assertions and this message that coding something that already exists is inherently bad. What happens is it starts to look like you are saying if you don’t use Symfony, you have a NIH problem. If your point is to show the value of collaboration, it is far more powerful to point to examples where you have been able to throw away large sections of your own code base to use that of another project.

    So, why should you code something that already exists? I’ve got 30 years of watching it done, and redone, and done again. Looking at this over the years, I suppose it’s important to do for a couple of reasons. First, we need new people learning how to code properly. But mainly, collectively, over the years, from Assembler and Cobol to PHP and JS, we are iterating code, building knowledge, strengthening infrastructure and we have been for a long, long time, before many of you were typing on keyboards, in order to reach a broader audience, faster, more securely, with a higher level of professionalism, all the time.

    Reply
  17. Lukas

    @Amy: the issue is that the way he was comparing. Paul was making a very incorrect conclusion that anything that is needed to run the tests illustrates “cross-package dependencies”. Yet if you look at the composer.json (which I would have expected Paul to be familiar with) then you would notice that infact the Validator component has ZERO dependencies beyond PHP itself:
    https://github.com/symfony/Validator/blob/master/composer.json

    So either Paul was not familiar with how composer works or he just made an oversight. In both cases I would hope he will make a public statement to correct himself.

    Or Paul actually thinks that any dependency (optional or hard) is to be avoided. This is what I and several others wanted to speak out against, because it does indeed mean that it lead to code duplication. In its most extreme form this could lead to NIH.

    Notice that I attempted to state exactly that in the very first reply to this blog post, however Paul did not react at all, though he did discuss the topic of test inclusion. Given that Paul ignored my comment, I feel its legitimate to interpret that it was neither lack of understanding of composer nor an oversight and so I understand the stronger rhetoric to oppose the underlying message (optional deps are bad) of this blog post.

    Reply
  18. Amy Stephen

    Lukas – Do you understand that you are saying exactly what he is saying? Your first post explains some of the reasons that Symfony has taken that approach. There is, at best, a difference of opinion as to how valuable decoupling is compared to other goals. I happen to agree that balance is generally best. No one has raised the issue of automated replication which can be a good alternative to redundancy and increase the functionality of self-contained components.

    You also seem to be splitting hairs on the definition of dependency. You are saying the dependency is optional (if you don’t want to use a certain feature), he is saying that in order to use all of the features intended, one must first install this. Others are adding Composer makes that seamless. But, isn’t it all the same point?

    What I am not understanding is this jump to NIH. Seriously, not getting that. Are there any examples Symfony can provide of functionality your project has dumped where the software from another project was used, instead? I’ve asked that question a few times, but I have yet to get an answer. That’s honestly starting to bother me when I see more and more claims of NIH from Symfony folks. So, please, answer that.

    In my opinion, having projects doing things different ways, focusing on different architectural goals, sharing the results, IS collaborating. It’s the knowledge that should be shared. I see that happening here. If we all share the same code base, then how are innovations going to manifest? Time will be spent arguing about goals instead of doing it and seeing how it turned out.

    Always a balance. Share code where it makes sense for your project goals (which could be about personal learning goals). Across projects, share knowledge always. From my perspective, that’s how innovation is encouraged and spread. Paul’s goal was to focus on 100% decoupling. Very good, Paul. Thanks for sharing some of what you learned.

    Reply
  19. Lukas

    @Amy: what you call “splitting hairs on the definition of dependency” is quite the crux for me. If being able to parse Yaml files in the Routing component via an optional dependency is somehow a bad idea then it does indeed promote NIH or at the very least significant code duplication.

    So either it means that a Routing component ought to implement Yaml parsing if it wants to be able to parse Yaml files (this would indeed be NIH). Or it means that I would expect my users to first come up with a Yaml format, use some generic Yaml loader to parse the data and then implement some logic to convert the resulting data structure into instances of the Routing component classes. This would seem like encouraging users to do NIH (ie. reimplementing more or less the same code over and over again).

    This is why I brought up the topic of bridges. If indeed Aura wants to keep out optional dependencies from the core components then they should at very least provide bridge components that provide the necessary logic to move data between components. If you then want to provide one separate bridge component for every possible permutation is another topic.

    Reply
  20. Amy Stephen

    Lukas – OK, well, I appreciate this is very important to you. I must admit, I’m not sure you heard me, but, it’s possible we just look at this so differently that it could take time to understand such diverse positions. I do appreciate your responses, very considerate, thank you.

    Reply
  21. Stan

    @Lukas I think with the last comment you are ignoring another possibility, which is the bridging aspect. Part of the problem with symfony/routing is that it’s “bridges”, like the one you mention with Yaml and the one I’ve alluded to elsewhere with annotations is bundled up into the package. This, to me, is poorly organized dependency management.

    Reply
  22. Stan

    @Lukas my apologies – I hadn’t read far enough down! Why not take something like symfony/routing and sub-split the “require-dev” use cases into other lighter bridge-type components? I’m curious what your thoughts/reactions are to that proposition.

    Reply
  23. Lukas

    @Stan: its a question of practicality. having a separate package for each optional dependency is certainly possible, but imho there is a point where it just gets annoying for the user. where to draw that line is not a clear cut thing. so yes we have bridges for some optional dependencies, but as you noticed not for all.

    Reply
  24. Lukas

    @Stan: btw its important to realize that “require-dev” is the wrong place to look for your argument. you ought to be looking at “suggest” this lists the actual optional dependencies. “require-dev” lists everything that is needed to run the tests, which has nothing to do with runtime behavior. for example we have had a discussion if we should include phpunit in “require-dev” but we would never add phpunit to the “suggest” section (and yes this means that all the tests depending on phpunit classes are also currently fataling unless you have phpunit installed and autoloaded somehow).

    so when i am talking about bridges, i am talking about bridge packages that have a hard dependency on the given component (f.e. routing) and a currently optional dependency (f.e. yaml). this way you could get rid of all optional dependencies, but you would then have hard dependencies in those bridges.

    so all bridges allow you to do is to turn optional dependencies into hard dependencies. which however again means that if you think no dependencies are ok, you effectively say that all bridge code should be rewritten in every project which is what commentors have called NIH.

    Reply
  25. Lukas

    @Amy: “Are there any examples Symfony can provide of functionality your project has dumped where the software from another project was used, instead?”

    i wasnt sure if i understood that part of your response. are you asking for examples where Symfony has adopted 3rd party code?

    symfony v1 was already based on several 3rd party libs, though some were forked, while others continued to be developed independently.

    that being said as part of v2 we dropped a lot of code. f.e. for logging we now use monolog (we used ZF1 log for a while), for unit testing we now use phpunit. several projects were “adopted” like twig and swiftmailer. while we increased the cooperation with other projects like doctrine, which we use for annotation parsing.

    actually we also considered sharing code for the event handling but in the end decided that there was no way to implement things in a way that would cover all the features and performance criteria of both projects, so only have very similar but not exactly the same code.

    btw monolog is essentially a port of a python lib logbook and assetic is a port webassets, also a python lib. in the same spirit Symfony2 also borrows a lot of concepts from Spring and django, bringing these concepts to the PHP world.

    my point is that what constitutes NIH is obviously a complex topic. was the creation of monolog NIH given that there were other log libs already? i would say now because it took some different approaches and made them available to the php world.

    in the same way i guess we seem to disagree on the topic if bridge code should be provided and if so how it should be packaged.

    Reply
  26. Amy Stephen

    Thank you, Lukas. I said, I am very impressed with Symfony and I was hoping that there were good examples, like those you just mentioned, where the project has demonstrated inclusiveness. Appreciate that, very much.

    Also, just wanted to say thanks to Paul and the others of you for your helpful posts. The last couple of days, I have been reviewing my code for dependencies. Really surprised at how coupled I had made things, many times for now good reason.

    What I like the most about open source is learning from some of the greatest minds in our industry. This post and the discussion helped me.

    Reply
  27. Pingback: On Decoupling and Dependencies: Answering The Critics of Aura’s Approach | Paul M. Jones

  28. Matt Robinson

    I think one reason this article got so many people riled stems from the faulty assumption that running the test suite of a component will reveal whether it can work without dependencies. All that will tell you is whether the _test suite_ has dependencies.

    Sure, Aura has only 1 package with hard dependencies and Symfony2 has 3 (or 0 and 2 if you ignore the framework component in each), but that’s not really the point. What you _correctly_ point out in a later article is the more important reason that decoupling is good; whether the components can interoperate freely with 3rd party libraries.

    In this respect, Aura and Symfony2 aren’t so different at all. Symfony2’s framework itself uses 3rd party libraries right out of the box, and in the other direction the components have been embedded standalone into other non-symfony projects like Drupal and EZPublish. They’ve also been used one at a time in gradual refactoring (which is how DailyMotion shifted their platform), and they’ve been used to make other frameworks.

    These were all considerations that were part of its design. It’s simply not true to say that Symfony2 was designed framework-first and components second, and it’s (sorry) kind of silly to make an argument about the level of decoupling based on running the test suite alone.

    In your defence, I can’t even install the Zend Escaper component (no dependencies) through Composer without it downloading the entire framework. But that’s not an architectural issue – it could go away with time and a little effort from the maintainers, and no changes to the code. I hope they fix it! I do look forward to mixing Aura, Zend and SF2 packages in future developments.

    Reply
  29. php training in Chennai

    Being a zend framework supporter I use to know more about Aura.This post gives me platform to learn something about Aura.I too emphasize that it was fully decoupled than symfony 2 and zend framework 2.

    Reply
  30. Pingback: On Libraries and Dependencies - Web Mozarts

Leave a Reply

Your email address will not be published. Required fields are marked *