Kjapp og trygg hosting for Wordpress

OOP: dependency injection og DRY, validator klasse i constructor

RAH

Medlem
Hei,

Klarer ikke helt å vri hodet mitt rundt dette, bli fornøyd og komme frem til hva som er "riktig" om du skal følge alle prinsippene til objektorientert programering.

Her er mitt utgangspunkt, en enkel Contact klasse. Det eneste som er påbudt er mobilnummeret (skal brukes til å sende SMS) og klassen trenger en MobileNumberValidator klasse.


PHP:
interface ValidatorInterface
{
	public function validate($subject);
}

Class MobileNumberValidator implements ValidatorInterface
{
	public function validate($mobile)
	{
		return true;
	}
}

class Contact {

	protected $firstname;
	protected $surname;
	protected $mobile;
	protected $email;
	protected $comment;

	protected $groups = array();

	protected $validator;

	public function __construct(MobileNumberValidator $validator, $mobile, $firstname = null, $lastname = null, $email = null, $comment = null, $groups = null)
	{
		$this->validator = $validator;

		$this->setMobile($mobile);
		// $this->setFirstname($firstname);
		// etc...
	}

	public function setMobile($mobile)
	{		
		if( ! $this->validator->validate($mobile))
			throw new InvalidArgumentException;

		$this->mobile = $mobile;
	}
}

Fordeler med koden over er at jeg kan bruke MobileNumberValidator klassen i flere sammenhenger, koden er lett å teste og det er lett å bytte ut klasser.

Ulempen er at jeg må ha med validatorklassen når jeg ønsker å lage et nytt kontaktobjekt. Dette er vel ikke helt hva man anser å være i strid med Don't Repeat Yourself-prinsippet (DRY), men det er jo nettopp det jeg gjør ved å lage et validator objekt før jeg kan lage en kontakt.

En kontakt må ha et mobilnummer, så nummeret må valideres. Hver gang.

Jeg ønsker å bruke klassen slik:
PHP:
$contact = new Contact("99999999");

Hvordan ville dere løst dette og fortsatt vist respekt til SOLID prinsippene til objektorientert programmering?
 

selbekk

Medlem
Hvorfor ikke bare gjøre validator-klassen din static? I konstruktøren din kan du bare kalle den statiske klassen sin validate() metode, sende in $this, og få et svar tilbake :)

Det er flott at du bruker litt tid på å bruke korrekt kodestruktur i scriptet ditt. Når det er sagt, ville jeg nok kanskje løst dette på en annen måte:

1: Validere input før det legges inn i objektet ditt.
Slik er Contact-objektet ditt "dummest" mulig, og slipper å tenke på noe annet enn å holde på dataen sin.
2: Implementere valideringslogikken direkte i metoden
Dette er fortsatt testbart, da du kan skrive en enhetstest mot den eksponerte isValid()-metoden din. Det er ikke like vakkert, men i et enkelt eksempel som du nevner over, vil det være mer enn godt nok.
 
Topp