I'm currently writing my own PHP Framework (yes, another one) for studying purposes. I'll actually try to use it as my graduation dissertation.

After two failed attempts, I've finally found a way to develop it in a modular architecture, like Zend and Symfony.

I have some loosely coupled modules that can work apart from each other, but their usability would be better if I stick them together.

Now I'm wondering the best way of integrate them. I'm not willing to put a module as requirement for the other, because this breaks the modular design.

My first idea was to create a different module that requires the other two and put them to work together. This would work fine when I have just two modules, but when I have a module that can be integrated with two or more modules I get lost.

Should I create one module for each possible integration? Or should I create just one module and put all integrations I could have there?

Am I clear? If not, I'll try to explain it better.


A practical example.

My Data Access Layer implements the Table Row Gateway pattern. I have a TableGatewayInterface and a default implementation TableGateway.

Imagine now that I want a table with a cache for the last queries. I can achive this with the Decorator pattern, creating a CachedTableGateway that depends on TableGateway and a cache component, let's say CacheInterface.

I don't need the cache, but it could be useful.

Should I embed this decorated implementation into the original package, creating a requirement to the cache component? Or should I create an "integration package" that requires both cache and table gateway?

  • How to organise a modular project? Think of each module as a project.
    – back2dos
    Commented Feb 26, 2014 at 14:01
  • I've changed the title to better reflect what I'm asking. Commented Feb 26, 2014 at 14:02
  • Requiring another module shouldn't be considered "bad" per se, as long as the first module doesn't depend on the implementation details of the second/required module.
    – Derek
    Commented Feb 26, 2014 at 15:25
  • No, everything is built over generic interfaces. The problem is that is possible to use the module without the other. It seems pointless to put the other module as a requirement if I may not use it. Commented Feb 26, 2014 at 16:56

1 Answer 1


If you are using the Decorator pattern, the CachedTableGateway package would implement the TableGatewayInterface and accept another TableGatewayInterface to forward the requests to that couldn't be found in the cache.

If you have a generic caching package, then the CachedTableGateway package could be implemented using that caching package and that naturally implies a 'requires' relationship between the packages.

Other than that they both implement the same interface, there is no relation between CachedTableGateway and TableGateway. It is up to the client code (which could include integration tests) to decorate a TableGateway with a CachedTableGateway.

  • Yes, sure. Did you mean I should put ChachedTableGateway in another package? Commented Feb 26, 2014 at 18:23
  • @HenriqueBarcelos: Yes, unless there is a compelling reason to have CachedTableGateway and TableGateway in the same package. Commented Feb 27, 2014 at 8:39
  • And should I create a new package por EVERY SINGLE INTEGRATION, or would it be better to create a "extended" version of the package with all integrations? Commented Feb 27, 2014 at 12:14
  • @HenriqueBarcelos: Perhaps we are talking at cross purposes and perhaps my understanding of your use of packages in PHP is flawed. If you have a modular system with one package that can be extended in several ways (each depending on different other modules), then each extension should be in a separate package, so that if the user wants to use the extension based on module A, it does not suddenly gets module B without needing/wanting it. Commented Feb 27, 2014 at 13:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.