We have an old and big PHP application with complex business logic. Now the project almost fully consists from spaghetti-code. I plan to do a smooth migration using Symfony e.g. rewrite some features using Symfony. Also seems DDD is a good choise for the project like this. So the main idea is to make a rewriting of some features to make it more clean and easy to maintain. Any suggestions?
Thanks.
DDD is a set of methodologies to facilitate team communication. It has less to do with refactoring and more to do with architecture.
I don't know if this qualify for SO, anyhow the explanation would be huge. There's no "silver bullet" method here. Personally I would try to isolate components, and migrate those one by one to a or several new Symfony application(s).
DDD is not relevant there. You can find many usefull pattern/methods in Martin Fowler books, especially "Refactoring" and "Patterns of Entreprise Architecture".
Actually the DDD principles can be applied in the context of a legacy code base refactoring. This is how we did (and are still doing it), but don't take it as a silver bullet:
Phase 1 - Strategic preparations:
1.) Use Context Mapping to identify Bounded Contexts and their integrations. Try to be agnostic towards your current architecture. This is actually very hard to do because of biases. It comes in handy if you do it with people that are no constant users of the old system.
2.) Sort the contexts by strategic value and identify your Core Domain (Where is the money?), eventually finding Supporting Sub Domains (parts of the system that support achieving your strategic goals) and Generic Sub Domains (things that are absolutely necessary, i.e. compliance and accounting).
3.) Bring Stakeholders, Developers and Product Owners together to form a common language, the Ubiquitous Language within the different Domains that capture the intents and capabilities of the business. Be dogmatic about a central dictionary of these terms, if you hear something ambiguous during discussions, resolve it and add it to the dictionary. This is an integral part of any DDD project since we are modelling the capabilities of the business, which means the code and the stakeholders language should carry the same semantics.
4.) OTPIONAL: Depending on the size and working methodologies of your organization, you might have to restructure it. Let Conway's Law work for you and create a certain feature gravity by reassigning teams and individuals to the different domains that you have identified earlier as value streams where the best and brightest should be working on the Core Domain. Enable direct communication interfaces between developers and stakeholders to work closely on specification and constantly distilling the Model.
Phase 2 - Implementation:
0.) If you have no experiences with such a complex refactoring, get external help (consultants) or hire experienced engineers that have done this before. Believe me, you will need it (I have learned it the hard way myself).
1.) Create a Bubble Context in which you are free to redesign your models and integrate it with the legacy system. There are a lot of integration patterns (you can find a nice summary of those patterns here and here. Always ask yourself if the context in question has enough strategic value and is bound to evolve over time and has to nicely respond to change in the future. In the end it is all about creating Software that is easy to change and refactor. Iterate, rinse and repeat. Always refactor the new code as early as you gain new insights from the business.
NOTE: Don't try to do too much. The Bounded Context's play very nicely as Microservices boundaries, but a lot of times people underestimate the complexities of a distributed system. If you don't have the availability and performance requirements that would require this architecture, then a well designed, modular monolith can be just the correct tool to get the stuff done.
EDIT
If you are interested in the Strategic part of DDD you MUST watch Paul Rayner's talk from DDDEU 16 here.