Ola,

In een ander topic zegt Wouter op een gegeven moment:

Wouter J op 02/03/2014 16:08:06

allereerst zou ik geen setters gebruiken voor id en value. Dat zijn verplichte waarden, geef die dus mee aan de constructor en nog mooier: gebruik een factory: Session::create('user', 'Ozzie')

Waarom zou je een factory gebruiken ipv een constructor?

Waarom...

<?php
$session = Session::create('user', 'Ozzie');
?>
en niet...

<?php
$session = new Session('user', 'Ozzie');
?>
Wat is het verschil/voordeel?
>> Wat wouter bedoelt is een soort of embedded Factorization.

Maar dat voegt in dit geval toch niks toe ten opzichte van $session = new Session('user', 'Ozzie') ? Of zie ik iets over het hoofd?
Nee, het is beter dan $session = new Session('user', 'Ozzie').

De constrictor van Session create een nieuwe session voor de gebruiker Ozzie.

Als die session al bestaat dan kan je beter dat checken met die static functie voor dat je helemaal een ojbect gaan creëren en opnieuw die session gaan initialiseren.

$session = new Session('user', 'Ozzie') creëert altijd een object.

$session = $Factory::creat('user', 'Ozzie'); check of dat session al bestaat als niet creëert een new.
Nu wordt het vreemd. Jij zegt dus dat een factory een bestaand object teruggeeft als dat object al bestaat?
Dat kan, maar niet altijd (bijv. session objecten hoeven een keer gecreëerd worden)
Als je al een session geïnitialiseerd hebt dan waarom ga je dat opnieuw starten!.
De session wordt niet opnieuw gestart. Het zijn losse key->value paren waar een class omheen wordt gebouwd. Waarom weet ik overigens ook niet.
Simo, 1 factory die precies weet hoe ALLE services aangemaakt moeten worden? Dat gaat volkomen tegen het SOLID (voornamelijk de SRP) principe in...

Factories bestaan er in 2 smaken:
- Factory class
- Factory method

In het geval van een klasse heb je een bepaalde klasse, 1 per object type, die weet hoe hij iets aanmaakt:
<?php
$audi = AudiFactory::createCar(new Tyres('Pirelli'), new Engine('V8'));
?>

In dit geval is het gebruik van een Factory class alleen maar duidelijk, een auto maakt zichzelf niet, de fabriek maakt de auto. In de meeste gevallen is dit echter een beetje overdone, dan is een Factory method genoeg.

Het Factory Method pattern gebruik ik echter wel veel. Wat we hierboven in de code voor problemen hebben:
- Strict genomen create ik geen auto, ik assemble een auto. Tyres en Engines manufacture ik.
- We hebben nu 1 object: Tyres die voor alle soorten banden werkt. Beter is hier bepaalde kwaliteiten van een band in te stellen doormiddel van het Strategy pattern. Zelfde geldt voor de motor.

Een mooiere code zou dan zijn:
<?php
$audi = AudiManufactory::assemble(Tyres::manufacture('pirelli'), Engine::assemble('V8'));

class Tyres
{
pub static func manufacture($type)
{
$tyre = new Tyres();
switch (strtolower($type)) {
case 'pirelli':
$tyre->milesBeforeWear(2000)->...;

// ...
}
}
}
?>
Wouter, maar waarom wil je in het voorbeeld met de Session class een factory gebruiken? Jij zegt omdat dat mooier is, maar waarom vind je het dan mooier?
Nou hier zie je al een duidelijk voorbeeld. Je wilt niet telkens al je initialzations aanpassen omdat je de constructor wat aanpast of omdat je wat andere waardes verwacht bij initialize. Je wilt maar 1 plek hoeven aanpassen.
>> Je wilt niet telkens al je initialzations aanpassen omdat je de constructor wat aanpast of omdat je wat andere waardes verwacht bij initialize.

Ik snap nog steeds niet wat je bedoelt eerlijk gezegd. Kun je een (pseudo) code voorbeeldje geven?
<?php

##########################
# 2014's Session.php #
##########################

class Session {

private static $request;

public static function request(Request $request = null) {
switch (func_num_args()) {
case 0:
return static::$request;
break;
case 1:
static::$request = $request;
break;
}
}

public static function create($key = FALSE, $value = FALSE) {
$args = func_get_args();
$array = array();

while (FALSE !== ($key = next($args)) && FALSE !== ($value = next($args))) {
$array[$key] = $value;
}

$session = new static(static::request());

foreach ($data as $key => $value) {
$session->set($key, $value);
}

return $session;
}

public function __construct(Request $request) {
// ...
}

}

##########################
# 2015's Session.php #
##########################

class Session {

private static $request;

public static function request(Request $request = null) {
switch (func_num_args()) {
case 0:
return static::$request;
break;
case 1:
static::$request = $request;
break;
}
}

// NEW!
private static $driver;

// NEW!
public static function driver(Session\Driver $driver = null) {
switch (func_num_args()) {
case 0:
return static::$driver;
break;
case 1:
static::$driver = $driver;
break;
}
}

public static function create($key = FALSE, $value = FALSE) {
$args = func_get_args();
$data = array();

while (FALSE !== ($key = next($args)) && FALSE !== ($value = next($args))) {
$data[$key] = $value;
}

$session = new static(static::request(), static::driver());

foreach ($data as $key => $value) {
$session->set($key, $value);
}

return $session;
}

// CHANGED!
public function __construct(Request $request, Session\Driver $driver) {
// ...
}

}

############################
# 2014's FourtyTwo.php #
############################

// Works!
$session = new Session($request);
$session->set('ford', 'prefect');
$session->set('marvin', 'the paranoid android');

// ...

// Works!
$session = Session::create('ford', 'prefect', 'marvin', 'the paranoid android');



############################
# 2015's FourtyTwo.php #
############################

// Broken!
$session = new Session($request); // error...
$session->set('ford', 'prefect');
$session->set('marvin', 'the paranoid android');

// ...

// Works!
$session = Session::create('ford', 'prefect', 'marvin', 'the paranoid android');

?>

Reageren