Using Composite Design Pattern in ORM Models in PHP 7 (Part 1: implementing Composite Design Pattern alone)
As may you now about the best practice of designing a recursive ordering system, the best technique is using a composite design pattern. So for getting a better insight about the project area lets talk about a sample project. Imagine a coffee shop that serves many types of coffees and many types of add-ins for coffees with specific prices. You want an ordering system that can handle the total amount of order and a list of order items. The best practice is using a unified abstract class. Lets call it Orderable (maybe you can find a better name for that but this is only an example). The implementation is:
so now we need the abstraction of attachable items. Coffee is attachable and can hold some add-ins but add-in is not attachable so we need this OrderableAttachable abstract layer:
as you can see we implemented the object stack that is useful for our order class and coffee abstract layer. This is for following DRY. No we need another abstraction of any items in the order that must implement the title and price of each item. This abstraction will use in both coffee and add-in abstraction. But there is a trick. PHP don’t support multi extends so our coffee class can’t extend the OrderableAttachable and this new OrderableItem. So we must to use this new class as a trait.
now we have all the main abstraction layers. Lets make a implementation for coffee and add-in.
now we need the final class for order itself.
so now we must to test it before moving forward and change our system to work in and ORM system. So lets make some concrete coffees and add-ins.
and lets test it like this:
the output will look likes this:
Order of
Turkish Coffee with Sugar and Milk : $5.9
France Coffee with Milk : $7.7
Total items: 5
Total amount: $13.6
Awesome! We use the power of composite design pattern in a coffee shop ordering system with php 7. but this is not enough. You can’t use this implementation in an ORM based system. Because ORMs have a Model Abstraction Layer that must be extends by each entity. And remember we are extending other class in our all three concrete classes: Coffee, Addin and Order. If you want to now the solution please wait a bit for me to write the Part #2: Merge Composite Design Pattern with ORM Abstract Layer