What is the best way to prevent wrong states in an object? This is the source of my question.
Basically my curiosity started with the intention of not letting a class exist with wrong values. Prevent programmers from making mistakes in class implementations and extensions.
I did not want a class to even bother to have to deal with a wrong value. I just wanted it not to be started if a wrong value of a given status or type was passed.
I work a lot with types in string, due to a demand for legacy code. For this I find it interesting to work with "value objects". That aparently is the primary design idea. I tried to go for something with stringly-typed (another new term I just found out).
So below I have the first example. The scenario is: a class need a type and instead invoke a string 'type_x' invoke a class and this class solving the value if it is valid. This class is the one we will see below.
/**
* StringlyTypeSecondOption
*/
class StringlyTypeFirstOption
{
private $type;
public static function type_1()
{
return new self('type_1');
}
public static function type_2()
{
return new self('type_2');
}
private function __construct(string $type)
{
$this->type = $type;
}
public function __toString()
{
return $this->type;
}
}
echo StringlyTypeFirstOption::type_2(); //here its ok
echo StringlyTypeFirstOption::type_3(); //here we have an error cause type_3 doesnt exists
This is a very good example because we havent no if or throw exception or any logic of verification. Is oop on its own. And I think its good.
And now we have the second example. Will provide a solution for the same problem I proposed.
class StringlyTypeSecondOption
{
private $type;
const TYPE1 = 'type_1';
const TYPE2 = 'type_2';
private const ALLOWED_TYPES = [StringlyTypeSecondOption::TYPE1, StringlyTypeSecondOption::TYPE2];
public static function factory($type)
{
if (!in_array($type, StringlyTypeSecondOption::ALLOWED_TYPES, true)) {
throw new Exception("Invalid type: {$type}");
}
return new self($type);
}
private function __construct(string $type)
{
$this->type = $type;
}
public function __toString()
{
return $this->type;
}
}
echo StringlyTypeSecondOption::factory('type_2'); //here its ok
echo StringlyTypeSecondOption::factory('type_3'); //here we have an exception cause type_3 doesnt exists
Is a very good example too but I already have some logic and is not so pure like the first one. But solve the problem like a charm too.
Both imlementations have strengths and weaknesses (I think). But if there is a consolidated design that fixes allowed values for a state of a class, what its name how to implement and what is the best oop beatiful and designed strategy to prevent an invalid value in an object?
I think this is more a discussion over an exact solution. If this was not the right place I ask the moderators to direct me to a better channel.
Thanks advance!
Aucun commentaire:
Enregistrer un commentaire