Answer the question
In order to leave comments, you need to log in
How can I refactor the given php function?
Hello.
Help, please, with the direction of thought.
I'm beginning to notice that this function, shown below as an example, is far from being an isolated case, but literally regular. I write very similar functions all the time that I can't refactor. At first they are simple, then they become more complicated and it turns out that in the example.
If I make a separate function for Start, and separately for Finish, then I will still have a duplicate code for obtaining data from the database (or transferring it to a third function :) ) and saving, which is the same for both Start and Finish. Neither option looks good.
public static function setUnits($type, $packageId, $clientSource, $clientDestination = NULL){
$package = Package::find($packageId);
if ($type == 'Start') {
$package->SourceUnitsStartJob = $clientSource->units + $clientSource->cost;
if ($clientDestination != NULL) {
$package->DestinationUnitsStartJob = $clientDestination->units + $clientDestination->cost;
}
}
if ($type == 'Finish') {
$package->SourceUnitsFinishJob = $clientSource->units;
if ($clientDestination != NULL) {
$package->DestinationUnitsFinishJob = $clientDestination->units;
}
}
$package->SourceUnitsLimit = $clientSource->unitsLimit;
if ($clientDestination != NULL) {
$package->DestinationUnitsLimit = $clientDestination->unitsLimit;
}
$package->save();
}
Answer the question
In order to leave comments, you need to log in
as I understand it, package is an active record
. Next, you have a class with methods (crutches like Util or Core) in which there is setUnits, this is an example of procedural code when the data is separate (in the package), and working with this data is elsewhere.
How would I improve this code.
1. I'm almost sure that you can get clientSource and clientDestination from package, it looks like AR objects too, so I would add links between models
2. I would remove this setUnits method
3. I would make the fields SourceUnitsFinishJob and DestinationUnitsFinishJob and DestinationUnitsStartJob and SourceUnitsStartJob so that they are calculated based on connections with clientSource and clientDestination, if your AR does not allow this, then I would make getting the value of these fields a method
Then getting some properties looked like this
$package = Package::find($packageId);
$package->clientSource->units; // SourceUnitsFinishJob
// и тд
// Чтобы получить поля DestinationUnitsStartJob которые расчитываются на основе двух параметров я бы сделал динамический атрибут
$package->destinationUnitsStartJob;
public function getDestinationUnitsStartJobAttribute()
{
return $this->clientDestination->units + $this->clientDestination->cost;
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question