Skip to content
Davor Minchorov

Building Maintainable PHP Applications: Thinking Data vs Thinking Business Processes

This article is part of the Building Maintainable PHP Applications series

Most tutorials on the internet as well as other formal or informal education, teach developers how to build projects with the CRUD mindset, which is highly technical and focuses on data manipulation, similar to what Excel was invented to do and has been doing its job for decades now.

This is understandable because the introductory material to programming needs to be simple and easy to consume.

Don’t get me wrong, the content is great for beginners, as a starting point, but when real world projects are built, they are more complex than what is being shown in the learning material.

Building a Twitter / Reddit / Facebook or any clone in a few hours is not really how you would build that if you were doing it for real. You would probably use different technologies for certain parts of the system.

This becomes a problem when every project in every context is being built this way.

Developers focus on the database and what columns it will have, what data types they will be and then they start writing the code based on the data in the database.

The problem with this mindset is that most businesses have their own processes and are unique in their own way.

Whenever a business process is executed, the process does not just save data in the database but rather:

  • It may validate the data based on specific business rules and requirements

  • It may talk to a 3rd party service integration

  • It may store the data into multiple databases or database tables

  • it may talk to multiple services or applications

which it’s very technical, and these things are implementation details. Business people and customers don’t care about the implementation details, all they care about is that the feature works.

As a new member on a project, you would probably have to guess what happens in the business process unless you ask questions for it from the product team or other engineers.

For example, think about what needs to happen whenever you place a new order on a food delivery service. It does not just create an order in the `orders` table.

This is why people invented a different approach to thinking in terms of business processes and behaviour of what is actually happening in the whole process from a business point of view.

The people who design the processes of the the food delivery service think about use cases like:

  • Choose the restaurant and the food to order

  • Apply coupon (if applicable)

  • Pay for the order

  • Approve Order

  • Take an order to deliver

  • Pick up order from restaurant

  • Take order to the customer delivery destination

  • Complete the order delivery

Some additional steps or business rules may apply here in order for the whole use case to be executed successfully.

As you can see, there’s no technical jargon included here, only behaviour is described.

In order to use this way of thinking, you, the developer, need to understand the business domain and how it works before you can write the code.

Also, it would be very beneficial if you name the classes, methods and properties exactly the same as the business people use them so that it’s easier for everyone to talk the same language and understand each other instead of business people having to learn technical terms.

Naming stuff becomes a lot easier, you don’t have to invent class names and method names, they are already there.

Designing the database and other infrastructure concerns is very important still but you shift the focus from the infrastructure concerns until much later in the development cycle.

You can design the business-related code without using any infrastructure.

The job now focuses on solving problems rather than just writing code and technicalities.

Let’s look at a code example and see the differences of the same code written with the CRUD mindset vs with the business process mindset when implementing a simple use case - member sign up:

1$member = new Member();
2 
3$member->id = $id;
4$member->firstName = $firstName;
5$member->lastName = $lastName;
6$member->emailAddress = $emailAddress;
7$member->status = $status;
8$member->password = bcrypt($password);
9 
10$member->save();

In this first example, the focus is on the insertion of the member in the database, which fields are being stored and how, which are implementation details (ActiveRecord is being used in the example here where each database column is linked to a property on the object. DataMapper is similar but the mapping and implementation is different). It does not show you what the business process is here. You wouldn’t be able to understand that from the code.

1$member = Member::signUp(
2 id: Id::createFromString(value: $this->memberRepository->generateIdentity()),
3 firstName: FirstName::createFromString(value: $signUpMember->firstName),
4 lastName: LastName::createFromString(value: $signUpMember->lastName),
5 emailAddress: $emailAddress,
6 status: StatusName::PENDING,
7 createdAt: $this->clock->now(),
8 updatedAt: $this->clock->now(),
9 password: Password::createFromString(value: $this->hasher->make(value: $signUpMember->password))
10);

In this second example, the focus is on the behaviour of the system, you can understand what’s happening with the system and how it works, it has a nice business-related method name. If you care about the implementation details and how the method is implemented, you can view the method itself.

This type of code (either one of the examples) is usually written in the application service or a command handler class.

These are simple examples, but think of a more complex example and how such code can help you understand the business better:

  • Order::place()

  • Reservation::make()

  • Order::fullfil()

  • Coupon::apply()

Remember that this way of thinking and writing code may take a while to get used to and it also depends very much on the context you are in.

It’s fine to use the CRUD approach for specific situations where there’s no specific business process, like a data management software.

It would be a lot easier to manage the complexity of the code, have more control over the code flow (what code should execute and when it should be executed) and understand the business with the business process thinking mindset in a very complex software which is in the following example categories:

  • Finance

  • Real Estate

  • Education

  • Health

and so on, you get the idea. These businesses are not mostly managing data but rather they have specific processes that happen on a daily basis.

Can you build software in these categories with the CRUD mindset? Sure, but it will be a lot harder to work with and manage the code.

I would highly recommend reading this article on this topic as well if you are interested to learn more.