How to concentrate on the business domain during development? How to be free?
In the era of information technology, more and more parts of everyday life are being improved by software. Technologies are progressing more and more and opportunities become unlimited. Consequently, the complexity of development is growing.
Programmers need to take care of as much detail as possible during the development of the software. Following the details during development, developers often lose the track of the business logic and domain to which the software relates. For this reason, it may happen that the client receives fully functional software as a result, but that solution does not fully meet the needs of the client.
What happens after that? Although the development of the software is complete, the client is not satisfied and updates are needed. Unplanned resources are wasted which jeopardizes the profitability of the project itself and the company's impressions.
The problem described is the worst possible situation that can happen. Serious companies, like ours, by the development of software not only include coding, but also detailed planning, project management and continues delivery. In other words, you need to do an analysis of the problem being solved, describe in detail the result that the client will get, make a detailed development plan, and the most important client needs to have constant insight into the work that has been done.
This will reduce the risk that the client will not be satisfied. In order to minimize risk, it is necessary to include developers in the process of verification. In this context, verification represents a reflection on the domain itself for which the software develops. Developers are in the "first line of defense" and if they can see the problem, their time and effort will be saved. In order for this to be possible developers need to relieve small technical things as much as possible. This can be achieved by programming techniques.
Let's describe an example
Let's say we are developing a system that has many entities. For each entity, we want to keep the information when it's created, when it's updated and is it deleted.
Example - User entity
App\Entity\User:
type: entity
repositoryClass: App\Repository\UserRepository
table: user
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
first_name:
type: string
lenght: 255
nullable: true
last_name:
type: string
lenght: 255
nullable: true
date_created:
type: datetime
nullable: false
date_updated:
type: datetime
nullable: false
deleted:
type: boolean
nullable: false
manyToOne:
profile_image:
targetEntity: ProfileImage
joinColumn:
name: profile_image_id
referencedColumnName: id
When we have provided the necessary data with the model, we must ensure that these data are adequately updated. We can do this every time we create or update an entity.
.
.
.
$user = new User();
$user->setFirstName($firstName);
$user->setLastName($lastName);
$user->setDateCreated(new \DateTime());
$user->setDateUpdated(new \DateTime());
$user->setDeleted(false);
. . .
What's the problem with this approach? The developer has to constantly think that when creating a new instance of an entity, it must necessarily set date_created, date_updated, and deleted. It should be noted that this example is just one of dozens.
Thinking about all these little things, the developer can come to a situation that absolutely ignores the business logic and domain in which the software relates. The solution is in a different approach.
For example, if we create an event listener that prior any changes over the database, sets the mentioned information instead of the developer, and the developer was aware that this would happen, the developer would never have to think about it again. One thing less to think about it.
EntityListener
class EntityListener
{
private $container;
function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function prePersist(LifecycleEventArgs $args)
{
$handler = EntityHandlerFactory::getHandler($args->getEntity(), $this->container);
if($handler == null)
{
return;
}
$handler->prePersist();
}
public function preUpdate(LifecycleEventArgs $args)
{
$handler = EntityHandlerFactory::getHandler($args->getEntity(), $this->container);
if($handler == null)
{
return;
}
$handler->preUpdate();
}
}
EntityListenerHandler
class EntityListenerHandler
{
protected $entity;
public function setEntity($entity)
{
$this->entity = $entity;
}
public function prePersist()
{
$this->entity->setDateCreated(new \DateTime());
$this->entity->setDateUpdated(new \DateTime());
$this->entity->setDeleted(false);
}
public function preUpdate()
{
$this->entity->setDateUpdated(new \DateTime());
}
}
This is just one small example of how to facilitate development coding techniques. What are your experiences? Have you encountered such problems and how did you solve them?