Hey guys,

Ik vroeg me ineens iets af. Een van de $_SERVER variabelen bevat een string met de encoding-types die de client ondersteunt.

Nu heb ik in mijn request\client object een method getEncodingTypes() gemaakt waarmee je die string kunt opvragen. Nu is mijn vraag... (ik heb namelijk echt geen idee of hier een "stelregel" voor geldt...) of je het beste kunt programmeren naar data of naar behaviour. Daarmee bedoel ik het volgende:

Hoe ik het nu doe, programmeer ik naar data. Namelijk:

<?php
$client = $request->getClient();
$encoding_types = $client->getEncodingTypes();
if (strpos($encoding_types, 'gzip')) {
// doe iets
}
?>
Wat er dus gebeurt, is dat ik data ophaal (de string met encoding-types) waarmee ik vervolgens iets ga doen (namelijk controleren of het type "gzip" aanwezig is).

Wat ik ook kan doen, is programmeren naar behaviour (gedrag/functionaliteit).
Voorbeeld:

<?php
$client = $request->getClient();
if ($client->hasEncoding('gzip')) {
// doe iets
}
?>
Hier haal ik dus geen data op, maar "vraag" ik aan de client of hij het encoding-type "gzip" heeft.

Heeft van deze 2 methodes eentje de voorkeur? Is daar een "stelregel" voor, of maakt het niks uit en is het net wat je zelf leuk vindt?
2e voorbeeld.
Het tweede voorbeeld, maar je hebt hier niet echt autonome klassen. Het bestaan van een client impliceert het bestaan van een server: zonder server geen clients. Vervolgens impliceert een response het bestaan van een request: een response is een antwoord op een request, zonder request geen response. Die delen daarbij een gemeenschappelijk toestand: wel of geen gzip gebruiken.

Je hebt hierdoor als het ware meerdere niveaus in collecties:

• client <--> server
• client{request} <--> server{response}
• client{request{content-encoding}} <--> server{response{compression}}

Misschien een ander voorbeeld verzinnen, want het eerste voorbeeld is niet per se onbruikbaar.
Het eerste voorbeeld, kort waarom dit zo moet zijn:

In een threaded language zoals C#.NET kan het bijvoorbeeld zo zijn dat je een "state" opvraagt.


if ( Obj.HasType("blaat") )
{
    var calc = DoeEenBerekening();
    var val = Obj.GetTypeValue("blaat");
    calc.value = val;
}


Het probleem wat je kan hebben is dat je eerst kijkt of "blaat" bestaat. Vervolgens zou een andere thread dat type weer verwijderd kunnen hebben door een ander request.
Vervolgens wil je wel "GetTypeValue()" aanroepen wat dan reslteert in vervelende fouten. Om dit te voorkomen heb je in die talen wel weer locking, maar het gaat om het principe.

In PHP heb je dan welliswaar niet zo zeer last van Threading problemen. Maar je zou het zelfde voorbeeld kunnen verplaatsen naar iets als wanneer je eerst checked of een record in je DB bestaat, en vervolgens haal je het er pas uit. Het zou tussen de "has" en "get" al verwijderd kunnen zijn.

Dit principe heet "Tell, don't ask". Als je meer info hier over wilt en meer voorbeeld wilt hebben dan zou ik gewoon het een en ander even doorlezen hierover:

http://martinfowler.com/bliki/TellDontAsk.html
https://www.google.nl/#q=tell+dont+ask+oop&safe=active
Bedankt voor jullie reacties.

@Ward: je uitleg is spot on. Je hebt inderdaad een client en server als onderdeel van het request. En een response als antwoord op dat request. In de response wil je dan via het request aan de client vragen of deze bijv. gzip ondersteunt.

@D Vivendi:
Ik snap (nog) niet helemaal nog wat je bedoelt eigenlijk :-s
Wat is precies het verschil of ik vraag welke types er aanwezig zijn (situatie a) of dat ik vraag of een specifiek type aanwezig is (situatie b)? Waarom is optie b volgens het "tell don't ask" principe niet goed?


Ook nog een andere vraag:

Ik zag dat mensen cheken met strpos of een bepaalde encoding method bestaat:

<?php
if (strpos($_SERVER['HTTP_ENCODING_TYPES'], 'gzip')) {
// doe iets
}
?>
Is dit niet een "tricky" manier van controleren? Stel dat er ook een encoding type "bugzip" zou bestaan, dan zou strpos een positief resultaat opleveren. Dat is dan toch geen veilige manier van controleren? Of zie ik dat verkeerd?
Hangt ook van de compressie van de response af. Het mag bijvoorbeeld ook 'deflate' zijn als je ergens ob_start('ob_gzhandler') wilt doen.

Niet-hoofdlettergevoelig controleren met stripos() in een Yoda-conditie met een strikte gelijkheid vind ik zelf netter. Kwestie van smaak:

<?php
if (
    false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') ||
    false !== stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate')
) {
    ob_start('ob_gzhandler');
}
?>
Je optie B is niet "tell, don't ask". Daar "ask" je juist iets -> "Heb je toevallig 'gzip' in je lijst zitten".

Ik heb al geprobeerd uit te leggen waarom je dat niet op jouw "B" manier wilt doen, maar juist volgens het "Tell, don't ask" pricipe. Er is zat leesvoer hier over te vinden, als je echt geintreseerd bent dan zoek je gewoon heel wat informatie op en neem je dat door. Daarna snap je het echt wel, het is geen rocket science.
@Ward:

Ik bedoel eigenlijk dit: stel dat er een comppressie methode "bugzip" bijkomt, dan zou "gzip" matchen met "bugzip". Hoe voorkom je zoiets? Strpos is toch niet echt een veilige manier om iets te controleren?

@D Vivendi:

Ik snap het principe niet. In het voorbeeld wordt gezegd dat je iets opvraagt, wat even later weg kan zijn. Echter, in dit geval haal je verder niks op. Je vraagt of de client iets ondersteunt. Het is niet zo dat de client dat het ene moment wel ondersteunt, en even later ineens niet meer. Vandaar dat ik niet begrijp op welke manier het "tell, don't ask" principe hier van toepassing is.
>> Strpos is toch niet echt een veilige manier om iets te controleren?

Al gezegd: HTTP is hier niet hoofdlettergevoelig. Als je daar omheen fietst met stripos() in plaats van strpos(), dan ben je er eigenlijk al, want de implementatie van ob_start('ob_gzhandler') in PHP controleert zelf achter de schermen al óf er een acceptabele compressie wordt gevraagd en past de gevraagde compressie vervolgens toe. Dat hoef je niet nog eens zelf na te bouwen.
Ik bedoelde eigenlijk wat anders, maar ik heb het denk ik niet heel duidelijk uitgelegd waarvoor mijn excuses.

Stel je hebt een string:

$string = "foo, barbarapappa";

Als je nu wil kijken of in die string de waarde "bar" aanwezig is, dan zou dat met strpos resulteren in een positief resultaat omdat barbarapappa een match oplevert. Echter, er is helemaal geen waarde "bar". Mijn idee is dan ook dat strpos geen veilige manier is om waardes in een string te controleren.

Reageren