Gå til innhold

PHP·pub - Programming With Attitude - and beer


Anbefalte innlegg

Hva er poenget med å returnere $this i alle de funksjonene? Det er iallfall ikke særlig pent. Dessuten, når har du behov for å endre host, brukernavn, passord og database midt inni eksekveringen (selv om det slik det er satt opp er helt umulig)?

Nei må jo ikke det, men så på en tutorial: http://www.talkphp.c...d-chaining.html

Wow! Det er en smule skremmende at vedkommende faktisk utvikler PHP, for det han viser der et kort og godt stygg programmering. Mitt største problem med det han viser der er at lesbarheten reduseres dramatisk. Det er på ingen måter åpenbart hva man operer på når man returnerer $this i hytt og gevær. Faktum er at man må enten ha dokumentasjon på klassene eller se selve kildekoden for å faktisk forså hva som skjer. For det andre er eksempelet ganske elendig i og med at dataene han setter i det minste burde vært satt i constructor og så blitt endres av set-funksjoner seinere. Slik det presenteres er introduce ubrukelig uten at setName og setAge er kjørt, noe som er langt fra heldig og gjør at objektene har et stadie hvor de er ubrukelige.

 

Er det ikke bedre med flere instanser av klassen og la disse innstillingene bli satt i constructor i stedet?

Kan du gi et lite eksempel her? :)

Noe ala denne metoden? http://www.phpriot.c...ith-spl-php-5/4

Det jeg er ute etter er at constructor aktivt benyttes. Den kjøres for å initialisere objektet, og det betyr at man bør sette initialverdier for alle variabler i klassen slik at objektet umiddelbart er i en brukbar tilstand og de fleste funksjoner kan benyttes (det kan finnes unntak, men databaser er ikke et av de i mine øyne). Eksempel:

class Example
{
   private $varA;
   private $varB;
   private $varC;

   public function __construct($paramA, $paramB)
   {
       $this->varA = $paramA;
       $this->varB = $paramB;
       $this->varC = 10;
   }
//...
};

 

Ja, og hva i alle dager er forresten poenget med å ha den SQL-klassen når du uansett ser ut til å bruke PDO? Hvorfor ikke bare bruke PDO? Hvor ligger fordelen i å ha det slik det er nå kontra å opprette PDO-objekter «selv» utenfor?

Nei, si det :D

Er det ikke noen fordeler og benytte "singleton" med PDO? (vet at jeg ikke bruker det her)

Joda, hvis du så absolutt ønsker et eneste objekt i spill så fungerer jo det. Det er dog normalt sett ikke en begrensning jeg ville ansett som akseptabel. Det er ingen umulighet at man ønsker tilgang til flere databaser samtidig, men det kommer såklart litt an på bruksområdet.
Lenke til kommentar
Videoannonse
Annonse

Speaking of method chaining på den måten der.

 

Hvorfor i svartsidige implementerer ikke flere programmeringsspråk "with"?

 

For å bruke samme eksempel som artiklen det linkes til ...

Person peter = new Person(/* Kanskje vi burde initialisere de kritiske variablene her? Neivel. Vi har muligheten for å opprette et unitialisert, mer eller mindre ubruklig objekt. Pyttsann ...*/)
With peter
.Name = "Peter"
.Name = "Winifred"
.Age = 72
End With

(Ettersom .NET støtter akksessorvariabler valgte å bruke det istedenfor funksjoner for å sette våre fantasivariabler.)

Lenke til kommentar

Det er standardsvaret de fleste har, likevel er jeg uenig.

 

Beats metoden den fyren i artiklen gjør ting på :p

 

 

Dessuten er det greit om man ønsker å sette en rekke verdier i objektinstanser man har gitt beskrivende navn.

 

Ideelt sett gjør man ikke det så ofte, men de gangene man gjør det er det sweet å slippe å skrive ett, si åtte-sifret, instansnavn mange ganger.

 

Dessuten gir det bedre readibility (syns jeg, da - mange syns det motsatte).

Lenke til kommentar

Ta en titt på Zend Framework for mer method chaining-mania, Ernie.

Huff, det er tydeligvis noen som synes dette er en god metode. Jeg holder meg allikevel til min umiddelbare mening. Dette er stygg og dårlig koding, og bryter på sett og vis med vanlig OOP. Det introduserer problemer i forhold til hva man faktisk opererer på og slik sett reduserer lesbarheten dramatisk med mindre man veit eksakt hva som er tanken bak det. Man er f.eks. tvunget til å bryte linjen og hente ut objektet som returneres straks man får en endring av kontekst (noe man riktignok fort bør gjøre uansett), ellers blir det plutselig ikke like åpenbart hva som skjer. Det introduserer også stadier hvor objektet kan være ubrukelig med mindre ytterligere metoder kjøres. Jeg ser ingen umiddelbar fordel med det her, og de eksemplene jeg hittil har sett virker å være mer eller mindre konstruert for å forsøke å fremheve at dette visstnok skal være mer lesbart. I virkeligheten gjøres bare alternativene (med vilje?) mer ulesbar enn nødvendig. Jeg tror mye av problematikken man forsøker å løse/forbedre med «method chaining» veldig lett kunne vært løst mer elegant v.hj.a strukturer e.l. i stedet for å effektivt konstruerere milelange linjer.

 

For eksempel så jeg setcookie bli nevnt i en blog om temaet. Greia er at dette ikke er lesbart:

setcookie("username", "cjoudrey", 0, null, ".cakemail.com");

Jeg er ikke uenig i det, men i stedet for å gå bananas med lange linjer og få f.eks.

Response::cookie("username")
   ->setValue("cjoudrey")
   ->setExpire(0)
   ->setDomain(".cakemail.com")
   ->set();

kunne man likegjerne gjort slik (eksempel i mer C/C++-ish kode)

CookieParameters cookie;
cookie.name = "username";
cookie.value = "cjoudrey";
cookie.expire = 0;
cookie.domain = ".cakemail.com";
setCookie(cookie);

Man ender riktignok opp med en linje mer, men det ligger ingen automatikk i at mindre kode er bedre. Koden kan iallfall umulig sies å være mindre lesbar, og ødelegger heller ikke . / -> som variabel/metode-operator.

Lenke til kommentar

Speaking of method chaining på den måten der.

 

Hvorfor i svartsidige implementerer ikke flere programmeringsspråk "with"?

 

For å bruke samme eksempel som artiklen det linkes til ...

Person peter = new Person(/* Kanskje vi burde initialisere de kritiske variablene her? Neivel. Vi har muligheten for å opprette et unitialisert, mer eller mindre ubruklig objekt. Pyttsann ...*/)
With peter
.Name = "Peter"
.Name = "Winifred"
.Age = 72
End With

(Ettersom .NET støtter akksessorvariabler valgte å bruke det istedenfor funksjoner for å sette våre fantasivariabler.)

With kan være bra det. Jeg ser ingenting i veien med With slik som implementert i vb.net eller c#

 

Det gir kortere kode, bedre lesbarhet, og jeg ser ingen negative sider. Scopet er klart, du vil aldri ha tvetydighet, ettersom du må bruke .(punktum) for å referere til objektet.

With foo 
   [b].[/b]eggs = "snake"
End With

 

Dette til motsetning til javascript, hvor du med with aldri kan forutse hvilket objekt som endres:

 

var bar = "spam";
var eggs = { bar: 45};

with (eggs){
 /*
 her vil du endre eggs.bar til "snake",
 */
 bar = "snake"; 

}
//eggs.bar er nå "snake"
//bar er nå "spam"

kontra

 

var foo = 23;
var bar = "spam";
var eggs = { };

with (eggs){
 /*
 her vil du IKKE endre eggs.bar, men variabelen bar til "snake"
 */
 bar = "snake"; 

}
//eggs.bar er nå udefinert
//bar er nå "snake"

 

With i python fungerer noe annerledes, der objektene kan definere egne handlinger som skal skje ved initialisering og avslutting av "with":

with open("hello.txt") as f:
   #bruk fila f

#her er fila f lukket,  for ved avslutting av with, vill f.__exit__ automatisk kjøres. 
#Denne exit-funksjonen på filobjekter kjører en så en .close kall på filobjektet.
# Hver klasse kan implementere sine egne __enter__ og __exit__ metoder. Disse vil da kjøres henholdsvis ved begynnelsen og slutten av en with-statement

 

 

Noe slik som with i python, kunne jeg tenkt meg i php også.

 

 

 

Ta en titt på Zend Framework for mer method chaining-mania, Ernie.

Huff, det er tydeligvis noen som synes dette er en god metode. Jeg holder meg allikevel til min umiddelbare mening. Dette er stygg og dårlig koding, og bryter på sett og vis med vanlig OOP. Det introduserer problemer i forhold til hva man faktisk opererer på og slik sett reduserer lesbarheten dramatisk med mindre man veit eksakt hva som er tanken bak det. Man er f.eks. tvunget til å bryte linjen og hente ut objektet som returneres straks man får en endring av kontekst (noe man riktignok fort bør gjøre uansett), ellers blir det plutselig ikke like åpenbart hva som skjer. Det introduserer også stadier hvor objektet kan være ubrukelig med mindre ytterligere metoder kjøres. Jeg ser ingen umiddelbar fordel med det her, og de eksemplene jeg hittil har sett virker å være mer eller mindre konstruert for å forsøke å fremheve at dette visstnok skal være mer lesbart. I virkeligheten gjøres bare alternativene (med vilje?) mer ulesbar enn nødvendig. Jeg tror mye av problematikken man forsøker å løse/forbedre med «method chaining» veldig lett kunne vært løst mer elegant v.hj.a strukturer e.l. i stedet for å effektivt konstruerere milelange linjer.

 

For eksempel så jeg setcookie bli nevnt i en blog om temaet. Greia er at dette ikke er lesbart:

setcookie("username", "cjoudrey", 0, null, ".cakemail.com");

Jeg er ikke uenig i det, men i stedet for å gå bananas med lange linjer og få f.eks.

Response::cookie("username")
   ->setValue("cjoudrey")
   ->setExpire(0)
   ->setDomain(".cakemail.com")
   ->set();

kunne man likegjerne gjort slik (eksempel i mer C/C++-ish kode)

CookieParameters cookie;
cookie.name = "username";
cookie.value = "cjoudrey";
cookie.expire = 0;
cookie.domain = ".cakemail.com";
setCookie(cookie);

Man ender riktignok opp med en linje mer, men det ligger ingen automatikk i at mindre kode er bedre. Koden kan iallfall umulig sies å være mindre lesbar, og ødelegger heller ikke . / -> som variabel/metode-operator.

 

rammeverket jquery til javascript benytter også chaining. Selvsagt skal du ikke chaine absolutt alt, men om du har flere objekter, gjør chaining det visuelt enklere å skille disse metodene (det er faktisk mulig å lage ei hel nettside med custom css og click-handlere med én eneste statement om du ønsker det).

 

Her er litt kode som demonstrerer chaining (Litt konstruert kanskje):


   jQuery("<div>inner</div>").appendTo("<div>outer</div>")
   .click( function(){
     jQuery(this).css("color", "green")
   })
   .parent()
      .appendTo("body")

 

Eksempelet lager en indre og ytre div. indre div får en klikk-handler, og den ytre diven plasseres i slutten av <body>. Skulle en skrevet dette uten chaining:

 


   var inner = jQuery("<div>inner</div>");
   inner.appendTo("<div>outer</div>");

   inner.click( function(){
     jQuery(this).css("color", "green")
   })

   inner.parent().appendTo("body")

 

Så det er mulig, men de fleste i jquery-miljøet liker å benytte chaining, iallefall til en viss grad.

Lenke til kommentar

With kan være bra det. Jeg ser ingenting i veien med With slik som implementert i vb.net eller c#

 

Det gir kortere kode, bedre lesbarhet, og jeg ser ingen negative sider. Scopet er klart, du vil aldri ha tvetydighet, ettersom du må bruke .(punktum) for å referere til objektet.

With foo 
   [b].[/b]eggs = "snake"
End With

 

Dette til motsetning til javascript, hvor du med with aldri kan forutse hvilket objekt som endres:

 

*Snip*

 

With i python fungerer noe annerledes, der objektene kan definere egne handlinger som skal skje ved initialisering og avslutting av "with":

with open("hello.txt") as f:
   #bruk fila f

#her er fila f lukket,  for ved avslutting av with, vill f.__exit__ automatisk kjøres. 
#Denne exit-funksjonen på filobjekter kjører en så en .close kall på filobjektet.
# Hver klasse kan implementere sine egne __enter__ og __exit__ metoder. Disse vil da kjøres henholdsvis ved begynnelsen og slutten av en with-statement

 

 

Noe slik som with i python, kunne jeg tenkt meg i php også.

 

 

Det er klart en god implementasjon er et must. Men det gjelder egentlig alt :)

Og hva javascript angår - er det noe i det språket som virker veldig gjennomtenkt?

Føler det er litt, tja, halvferdig :p

Genistreken med VBs implementasjon er at om man ikke har "." forran, så kjører man mer eller mindre vanlig kode, og kan manipulere andre objekter.

 

Jeg snakker (vel, skriver ...) ikke Python, så jeg vet ikke - men det du beskriver høres mistenklig ut som using i .NET. Kan det stemme?

 

 

En ting til, dessverre valgte Microsoft å ikke ha støtte for With i C# (til min store irritasjon). Lett å anta at C# har støtte for det (slik du gjør), men MS har av mystiske grunner valgt å gi VB.NET en del treats jeg sikler etter i C# (vice versa).

Lenke til kommentar

 

rammeverket jquery til javascript benytter også chaining. Selvsagt skal du ikke chaine absolutt alt, men om du har flere objekter, gjør chaining det visuelt enklere å skille disse metodene (det er faktisk mulig å lage ei hel nettside med custom css og click-handlere med én eneste statement om du ønsker det).

 

Her er litt kode som demonstrerer chaining (Litt konstruert kanskje):


   jQuery("<div>inner</div>").appendTo("<div>outer</div>")
   .click( function(){
     jQuery(this).css("color", "green")
   })
   .parent()
      .appendTo("body")

 

Eksempelet lager en indre og ytre div. indre div får en klikk-handler, og den ytre diven plasseres i slutten av <body>. Skulle en skrevet dette uten chaining:

 


   var inner = jQuery("<div>inner</div>");
   inner.appendTo("<div>outer</div>");

   inner.click( function(){
     jQuery(this).css("color", "green")
   })

   inner.parent().appendTo("body")

 

Så det er mulig, men de fleste i jquery-miljøet liker å benytte chaining, iallefall til en viss grad.

... og hva er fordelen ved å gjør det slik? Hva er poenget med å ha en så lang linje når den blir så mye verre å debugge? Jeg kan iallfall se problemer med fremgangsmåten. Primært har man ingen mulighet til å indikere om ting går bra fordi objektet man operer på MÅ sendes tilbake. Det er et problem når input bør valideres. Riktignok, «exceptions» kan brukes til formålet, men da er man jo også låst til det.

 

En ting som riktignok ikke er aktuelt i PHP (eller JS for den del) er at «method chaning» gjør det særdeles interessant å få klassen «thread safe». Det er vel i praksis ikke særlig gjennomførbart med mindre man har en bestemt funksjon som skal kjøres i starten og en bestemt funksjon som avslutter det hele.

Lenke til kommentar

En ting som riktignok ikke er aktuelt i PHP (eller JS for den del) er at «method chaning» gjør det særdeles interessant å få klassen «thread safe». Det er vel i praksis ikke særlig gjennomførbart med mindre man har en bestemt funksjon som skal kjøres i starten og en bestemt funksjon som avslutter det hele.

Nå veit jeg ikke med php, men javascript er enkelttrådet. Da bør vel safe-threading ikke noe tema?

 

Fordelen med chaining er jo at det er mer oversiktelig(subjektivt), samt at prototyping blir enklere. koden blir også mindre når du kjører den igjennom en minificator, slik som google closure compiler: http://closure-compiler.appspot.com/home

 

Tar jeg begge eksemplene over, får jeg følgende filstørrelser

 

med chaining

Original Size: 141 bytes (130 bytes gzipped)

Compiled Size: 135 bytes (123 bytes gzipped)

 

uten chaining:

Original Size: 172 bytes (140 bytes gzipped)

Compiled Size: 163 bytes (134 bytes gzipped)

 

Nå er jo eksemplet over veldig banalt, men i javascript hvor filstørrelse virkelig teller for performance, kan chaining spare deg for litt plass.

 

Debugging fungerer uansett strålende med firebug.

Endret av dabear
Lenke til kommentar

With kan være bra det. Jeg ser ingenting i veien med With slik som implementert i vb.net eller c#

 

 

with open("hello.txt") as f:
   #bruk fila f

#her er fila f lukket,  for ved avslutting av with, vill f.__exit__ automatisk kjøres. 
#Denne exit-funksjonen på filobjekter kjører en så en .close kall på filobjektet.
# Hver klasse kan implementere sine egne __enter__ og __exit__ metoder. Disse vil da kjøres henholdsvis ved begynnelsen og slutten av en with-statement

 

 

Noe slik som with i python, kunne jeg tenkt meg i php også.

 

 

Jeg snakker (vel, skriver ...) ikke Python, så jeg vet ikke - men det du beskriver høres mistenklig ut som using i .NET. Kan det stemme?

 

 

Det er vel noe av det samme, men i python kan du dynamisk endre __enter__ og __exit__ metodene når som helst. Alle klasser (og objekter) kan ha disse metodene, du trenger ikke implementere et IDisposable interface slik som i .net.

Lenke til kommentar

Det er meget gode eksempler på bra programmeringsvaner, men de sier ingen ting om hvordan å bygge opp et system fra bunnen av, hvilket det virker som du sliter mest med.

 

Som kommentert på linken:

Also a complete example like CRUD operations with DB configurations will be useful.

Hadde vært fint med noen slike eksempeler også! :)

 

 

La oss si du har 1000 aktive brukere på en gang, hvordan ville du laget database-tilkoblingen? Hvordan ville du kallet på den/Hvor ofte?

Lenke til kommentar
  • 4 uker senere...

Driver med en klasse nå der det vil være hensiktsmessig å strukturere den noe alá:

$a = new class();
$a->b->d('data1');
$a->b->e('data2');
$a->c->f('data3');
$a->g('data3');

 

Hva kalles dette, og hvordan gjøres det i praksis?

 

__construct-funksjon i objekt a som initialiserer objekt b og c?

 

Eksempel fra jpgpraph-biblioteket:

$g = new Graph(300,200);
$g->SetMargin(30,20,40,30);
$g->title->Set("Natural cubic splines");
$g->title->SetFont(FF_ARIAL,FS_NORMAL,12);
$g->subtitle->Set('(Control points shown in red)');
$g->subtitle->SetColor('darkred');
$g->SetMarginColor('lightblue');

 

Løsning:

 

	class a{
	var $b;
	function __construct(){
		$this->b = new b();

	}
}

class b{
	public function c(){
		echo 'function c';
	}
}

$a = new a();
$a->b->c();

 

Gir da "function c1" selvfølgelig

Endret av cvłñ
Lenke til kommentar

Er bare å la medlemmene være objekter, ikke noe hokus pokus. Det regnes dog som dårlig praksis å initialisere objekter i konstruktøren. Bedre å «injecte» objektene via konstruktørparametere eller setter-metoder.

Kunne du utdype hvorfor du mener dette? Jeg ser ikke noe som helst problem i å opprette objekter i en constructor så lenge de også blir slettet i destructor. At noen skulle mene det er dårlig praksis høres helt fjernt ut for min del, iallfall uten noen konkret begrunnelse.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...