Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

martinszeltins's avatar

How to write code so that when requirements change it doesn't become a mess?

Very often the requirements change for the application and it becomes hard to change the existing codebase. What are some advice / tips for writing an app that will be easy to change later? How not to hard-code things? Any advice?

For example my boss came to me and said.. oh you know what we actually need this thing to be like this... but it wasn't originally intended for that so I'd need to rewrite half of my code... :(

0 likes
7 replies
automica's avatar

This is a bit of a big one to answer to be honest, but I'll try anyway, with an explanation of the worst project I've came across in my 20 years of contracting.

A client I worked with a few years back had a project they'd started back in early 2000s, It had had contractors and full timers working on it, and one of the php files (it wasn't even a class) had 7000 lines, and was a mix of css, js, sql queries and html markup.

No-one wanted to do any modifications to the file as it was a whopper and as a result, a lot of code got duplicated, and with every new feature, the soup got bigger.

Why was it a problem?

  1. no-one knew what was going on with it. things broke.
  2. the file was too large & logic was mixed with markup.
  3. formatting was inconsistent & there was no coding style.

so to fix that

  1. write some tests. make sure every bit of functionality has a test to cover its functionality. TBH make sure you write new tests before you write functionality. TDD. We're doing MVC in Laravel so that's should be ok. Being able to understand how to test code makes its easier to write code.
  2. make it smaller. Split up your code and views. Make smaller classes with related functionality. Use DI
  3. be consistent. follow coding standards. PSR-2

They didn't want to fix it, so I left and went to another company (where I've been for 2 years).

Theres a huge amount of resources on Laracasts that will help here. Below are a few that have stuck with me:

  1. https://laracasts.com/series/solid-principles-in-php
  2. https://laracasts.com/series/whip-monstrous-code-into-shape
  3. https://laracasts.com/series/ten-techniques-for-cleaner-code

I also discovered 'Object Calisthenics'

"Object Calisthenics are programming exercises, formalized as a set of 9 rules invented by Jeff Bay in his book The ThoughtWorks Anthology. The word Object is related to Object Oriented Programming. The word Calisthenics is derived from greek, and means exercises under the context of gymnastics. By trying to follow these rules as much as possible, you will naturally change how you write code. It doesn’t mean you have to follow all these rules, all the time. Find your balance with these rules, use some of them only if you feel comfortable with them.

These rules focus on maintainability, readability, testability, and comprehensibility of your code. If you already write code that is maintainable, readable, testable, and comprehensible, then these rules will help you write code that is more maintainable, more readable, more testable, and more comprehensible."

  • Only One Level Of Indentation Per Method
  • Don’t Use The ELSE Keyword
  • Wrap All Primitives And Strings
  • First Class Collections
  • One Dot Per Line
  • Don’t Abbreviate
  • Keep All Entities Small
  • No Classes With More Than Two Instance Variables
  • No Getters/Setters/Properties

see

In essence:

Make sure you understand what your code does, and its covered with tests before you make any changes. Also be sure to only work on a branch of your codebase to do your refactor so that if for any reason your new code isnt production ready, you don't break your main site.

Good luck!

2 likes
laracoft's avatar

@martinzeltin

I came across a very promising approach here https://github.com/lucid-architecture/laravel

It is not widely adopted yet, but I like that they have good rules dictating where code should go and it has been able to cover a lot of use cases. Personally, I'm not using it yet, but the author started with the problem of prevent mess from change over time.

martinszeltins's avatar

@automica Thanks, I'd like to continue this conversation if I may.

Yes, I definitely don't want to be the person who writes 7000 lines of bad code in a single file.

I am curious about a Single Page front-end application. Where I had not anticipated that there would need to be more sub-categories or the printing logic requirements changed to be very different now. So it requires me to re-write a lot of the front-end code. I wonder if this could have been avoided somehow? I am using a front-end framework where everything is split up in nice little components. But when the requirements changed, I still ended up having to change a lot of it. Is this normal or is it due to my bad architecture?

automica's avatar

rewrites are inevitable and I would rather rewrite something based on new requirements that spend 6 months planning it and building it once. the first is called agile development, the second approach is waterfall.

commercially agile seems to be the most practical approach, and its important (whilst guessing a bit) to only build what you need. indeed the term YAGNI - you aint going to need it - discourages code bloat. Writing a test to describe functionality and then writing the minimum amount of code to make your test pass is key also.

With SPA's its going to be a bit of a hit when you've got to rewrite code, so its often best to understand the changes and then perhaps built it again with the new knowledge you've got.

As a commercial web developers, we need people to change their mind and want changes in their apps otherwise we don't get paid. Our job our code the best we can (at this time) and make it so that anyone else who works on your project has the best chance of understanding what what we've done and why we have done it.

1 like
artcore's avatar

I came across lucid-architecture about a year ago and adopted it. It's basically command bus design pattern which helps to write single responsibility code base. The most important take away is that it makes refactoring/rewrites super easy imho and you KNOW which file to go to for THAT particular action.

Which reminds me that I also sprinkled in ActionDomainResponse or single method controllers (with __invoke()) which I use for ajax sometimes (e.g. mark invoice paid)

Taylor believes in fat Models but I'd rather use Laravel's queuable jobs (command bus) which for me is the key to write SRP. e.g. notify a user in the user model is not my ideal... even as Trait

laracoft's avatar

@artcore

I can see how lucid is similar to a command bus, but what do you mean by fat models, queueable jobs and notifiable?

The notifiable trait helps me put the user's email or group's ID "where it belongs", e.g. A notifiable class AdminChatGroup has routeNotificationForDiscord() which returns it's unique Discord URL.

I'm really trying to understand better, not trying to disagree with you.

artcore's avatar

@laracoft

I dont use Eloquent anymore and my example was from memory. It was perhaps a silly example of how the Model gets to be the bucket for certain functionality while I rather create a class for it that does just that and nothing else.

And a job, queueable or not is what I chose to use.

Laravel extended the command bus pattern with queueable async handlers: command bus on steroids. Which is why mentioned 'queuable'.

I like it when ppl disagree with me, a new chance to prove I'm right :) or not, and thus learn!

Please or to participate in this conversation.