A definition of a Model

Today I’m going to talk about an important concept in what is called Model-View Controller. And it has Model in its name, the pattern I’m going to discuss here. So now what is the definition of a Model?

A lot of developers know about models or have worked with it. But its not always clear what exactly a model is. Questions like what kind of data and methods should be in a model? What are best practices when dealing with models? And what exactly defines a model? My goal here is to try answer these questions.

Definition of Model

A model is an object that represents something that shows what it looks like or how it works. The model is smaller then the object it represents.

So a model represents something. It models something in the real world to something in software. If our business have Users in the real world, then we can create an object named Users to represents that real life model in software.

But is this really the correct and complete definition of a Model in software? Some people think not. It might sound correct, but a Model is more then this.

A lot of developers are confused by this definition and just use a model as a class with methods, all seemingly related but far from a real mode. Your models should be logical and should have a single purpose. The methods should all be related to it and not be a big 1000 lines class.

The best way to look at models is see it as a layer. There are different kind of models all with a purpose. So when you talk about models, then you talk about a layer in MVC. So is this the correct definition of a model? I guess it is! Now lets see what types of models we can use.

The different kind of models

Web MVC

So now look at the scheme of this web variant of MVC. You can see here that we have 3 layers. Can you see where the Model is? Yes its a the layer which communicates with the Controller.

So then the question is, how does this Model layer looks like? Well in proper MVC this contains all the business logic and is mostly made out of 3 types of structures. Lets go over them.

Domain Object or Entity

This your your container of purely domain logic. It represents your logical entity in the problem domain space. This is directly referred to as your business logic. In here you define what we call our domain object. For example. What is an Order? What data does it have? The methods in here define the business logic of a single Order Object. It’s also important that this object does not have any knowledge about its persistence. This object should have no knowledge about anything else. Your business logic is precious and should not depend on anything. Threat it well, its the heart of your application.

class Order
{
    /**
     * @var int
     */
    private $id;

    /**
     * @var string
     */
    private $title;

    /**
     * @var float
     */
    private $price;

   /* Your getter and setters */

   /* Your methods that are directly related to the Order object */
}

Data Mappers or Repository

The Data Mappers single purpose is to be responsible for the storage. In these objects your SQL queries life. I repeat, their single purpose is to map your domain object to the database. And this without any knowledge of the domain objects itself. This means no business logic should be here. You can also use the Repository pattern here to deal with persistence.

interface OrderRepositoryInterface
{
    public function findById(int $orderId): Order;
    public function findAll(): array;
    public function save(Order $order): bool;
}

Services

Services are your higher level Domain Objects. They are not responsible for the business logic but their single responsibility is for the interaction between the Domain Objects and Data Mappers. A service is also your public interface between the Model layer and the Controller layer. You should use services in your controller and not directly work with your Domain objects or Repositories in your controller.

<?php
final class OrderService implements OrderServiceInterface
{
    
    /**
     * @var OrderRepositoryInterface
     */
    private $orderRepository;

    /**
     * @var EventDispatcherInterface
     */
    private $eventDispatcher;

    /**
     * OrderService constructor.
     * @param OrderRepositoryInterface $orderRepository
     * @param EventDispatcherInterface $eventDispatcher
     */
    public function __construct(
        OrderRepositoryInterface $orderRepository,
        EventDispatcherInterface $eventDispatcher
    ) {
        $this->orderRepository = $orderRepository;
        $this->eventDispatcher = $eventDispatcher;
    }

    /**
     * @param Order $order
     */
    public function create(Order $order): void
    {
        $this->eventDispatcher->dispatch(OrderEvent::CREATED, new OrderEvent($order));
        $this->calculateAndSave($order);
    }

    /**
     * @param Order $order
     */
    private function calculateAndSave(Order $order)
    {
        $order->calculateTotalPrice();

        $this->orderRepository->save($order);
    }

}

Do we really need Services?

If you want to have clean code and architecture with the least possible technical debt? Then the answer is yes. The services handle the communication between the Model and other layers. This helps us to enforce SRP and makes the Model layer less coupled from the rest of your application. Another benefit is that this makes your controllers as simple as possible. Their only single responsibility is to handle requests.

What this also allows us is to decouple all business logic from controllers. If we have a REST API we can directly use the same services as we do in our user interface. And our controllers also have no way to affect the business logic.

Not using services might be an option for smaller projects, but I don’t ever recommend it for projects that might become bigger.

Is MVC the only architecture with Models?

I used MVC here in this example, even though I don’t use or recommend it this way in most projects. But in my opinion this is the best and easiest architecture to explain about models. You can use different layered architectures but in most architectures you have the same 3 types of model structures. Its more about where you place what structure and where your public interfaces and boundaries are. But that’s something for another blog post.

What in case we use something like MVVM?

We also have MVVM  (Model-View-View Model) which uses a View Model. This is used in frameworks like Magento. As an extra layer we have a View Model here. Well in short the Model holds your business logic while the View Model holds your application logic. The controller in this case (if any) only handles requests. While the View Model is in charge of handling the application logic and using your Models. In this case you don’t need a Service Model, because your View Model kinda handles the responsibilities a Service Model does.

Conclusion

The conclusion as always is to think before you code. You should have a clear knowledge about what a model is, and what type’s of structures it represents. Use those structures and master them. Always keep the SOLID principles in the back of your mind and decouple your code as much as possible. And remember when you talk about Models next time. Its a layer with different kind of structures.