I am going to create a new project with ZF2 . In fact I'll have to upgrade a project ZF1 but I decided to start from scratch.
My project is very large and has already been translated into 10 different languages by volunteers from all parts of the world.
The difficulty I am having is the analysis of the structure of the modules that ZF2 tells me to follow.
The software allows SMEs in the world of ISPs to manage their customer database , services, orders, invoices , domains , technical assistance , ecommerce, kb, and much more.
Assuming that ZF2 encourages programmers to create small modules reusable in other applications , and that in all cases we try to simplify and abstract as much as possible the structure of classes , many tables in the database of the project are connected to each other through various foreign keys and i can not understand how to create independent modules with their own files of entities and at the same time being disconnected from the project without causing a crash .
For example :
My application runs :
- Customers
- Orders
- Invoices
- Payments
- Messages
- Private Notes
Here is a screenshot of the web interface of the Project :
As you can see the project shows as much as possible an overview of the law and order situation by embedding various sections of the same project . Initially I thought of creating a single module but I need some advice from you.
What strategy would you advise me to adopt a structure of a large project?
Modules can be a lot. And they can be barely anything at all. That's the charm of them. Try to not think overly complicated. Think of a
NewsModule
and aCategoriesModule
. Think about gluing those two together. If you can manage that, a big project like yours will be just as simple. If you can not manage it, you'd better be advised to wait with starting your new project until you can do so.Ultimately, big projects are always a mess. A mess in a sense that when you look at the first lines of code you write you'll feel shocked when you do so a year or two later. The ability to refactor code-segments is very important and that's precisely why you should separate the concerns of each of your modules as much as possible.
For a start, your "My application runs"-List appears to be a good first separation of independent Modules. The trick is to keep the interfaces simple so that adapters are easily interchangeable (Customer <-> Orders).
I myself am currently working on a very large scale project in ZF2 and believe the key to success is embracing the modularity that the framework offers.
Some pointers I feel would be helpful :
Create an abstract/base module
Creating a "base" module will allow you to contain most of the shared/abstract interfaces/classes that could be used in any module. This will mean that the base module is a dependency of each other module within the system.
Modules have inter-dependencies
Some modules, although separated will depend on functionality of other modules (payments may need information on users for example).
You should carefully think about what these services are and ensure that although they are shared, you do not start introducing coupling/code duplication in each module.
I make extensive use of the
forward()
plugin, which allows me to call another controller action from within another and build a aggregated views, while still keeping each module encapsulated in their own modules.An effective service layer
Really a general MVC design principle, however ensure you are not coding business logic within a controller but rather use 'service' classes injected into your controllers. If you don't you will quickly find it unmanageable.
Create Service Factories
Prefer concrete factory classes (classes implementing
Zend\ServiceManager\FactoryInterface
) as apposed to closures otherwise you will quickly find that the number of factories you need will bloat yourModule.php
and these cannot be cached like the configuration - meaning a performance hitViewPlugins/Controller Plugins
Abuse the flexibility of controller and view plugins. These are extremely powerful ways to encapsulate and inject additional view/controller logic without having to extend existing classes.
Forms
Forms can be a pain as there is allot of dependencies that tend to need to be met. I think its essential to create reusable fieldsets that map directly to you domain model (entities). All the input filters/hydrators are then attached to this fieldset and should you wish to use them all you need to do is attach it to a form.
If you have have a
CompanyFieldset
for instance, you could reuse it inCompanyEditForm
andCompanyCreateForm
andCompanyEditForm
An example from my project:
In terms to your modules :
This seems like a good list of self contained modules to begin with.
I'm sure there is more, i'll update if I can think of anything