I have been reading a lot of material on how to become better in OOP, DDD etc. While reading Object calisthenics and Getters/Setters. Evil. Period. I got confused. Let me explain it by example.
I have this organization class, representing the information about organization, the classic entity:
class Organization
{
private $name;
private $city;
private $street;
private $phone;
private $email;
public function __construct($name, $city, $street, $phone, $email)
{
$this->name = $name;
$this->city = $city;
$this->street = $street;
$this->phone = $phone;
$this->email = $email;
}
public function getName()
{
....
}
public function getCity()
{
....
}
public function setCity($newCity)
{
....
}
public function getStreet()
{
....
}
public function setStreet($newStreet)
{
....
}
public function getPhone()
{
....
}
public function getEmail()
{
....
}
public function setPhone($newPhoneNumber)
{
....
}
}
The organization name, city, street, phone and email may change, so the setters looks kind a logical. Getters are used to to display the properties of organization in table. How can I remove the boilerplate code and break trough from this anemic model? Maybe this is the case where the getter/setter is unavoidable?
Also object initialization using __construct
. Is it a good practice to pass so many instance variables to constructor?
I gave it a try, according to what I read. Created some ValueObject
to store information and do validation (don't know if the ValueObject
should do a validation on its data):
class Phone
{
private $phone;
public function __construct($phone)
{
if (!$this->validate($phone)) {
throw new InvalidPhoneNumberException();
}
$this->phone = $phone;
}
public function getPhone()
{
return $this->phone;
}
private function validate($phone)
{
// validate the phone number
}
}
class Email
{
private $email;
public function __construct($email)
{
if (!$this->validate($email)) {
throw new InvalidEmailAddressException();
}
$this->email = $email;
}
public function getEmail()
{
return $this->email;
}
private function validate($email)
{
// validate email
}
}
class Address
{
private $city;
private $street;
public function __construct($city, $street)
{
$this->city= $city;
$this->street = $street;
}
public function getCity()
{
return $this->city;
}
public function getStreet()
{
return $this->street;
}
}
Then passed these objects instead of string representations of data to my Organization and did some renaming on methods:
class Organization
{
private $name;
private $address;
private $phone;
private $email;
public function __construct($name, Address $address, Phone $phone, Email $email)
{
$this->name = $name;
$this->address = $address;
$this->phone = $phone;
$this->email = $email;
}
public function getName()
{
return $this->name;
}
public function getAddress()
{
return $this->address;
}
public function getPhone()
{
return $this->phone;
}
public function getEmail()
{
return $this->email;
}
public function changeAddress(Address $newAddress)
{
$this->address = $newAddress;
}
public function changePhoneNumber(Phone $newPhoneNumber)
{
$this->phone = $newPhoneNumber;
}
}
Does this code smells less and looks more mature from the perspective of OOP?
Aucun commentaire:
Enregistrer un commentaire