Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > it.comp.www.php > #22357 > unrolled thread

parent::__contruct() prima o dopo

Started byalex <1j9448a02@lnx159sneakemail.com.invalid>
First post2018-11-23 08:51 +0100
Last post2018-11-27 08:25 +0100
Articles 15 — 4 participants

Back to article view | Back to it.comp.www.php


Contents

  parent::__contruct() prima o dopo alex <1j9448a02@lnx159sneakemail.com.invalid> - 2018-11-23 08:51 +0100
    Re: parent::__contruct() prima o dopo Alessandro Pellizzari <shuriken@amiran.it> - 2018-11-24 09:07 +0000
      Re: parent::__contruct() prima o dopo alex <1j9448a02@lnx159sneakemail.com.invalid> - 2018-11-24 14:39 +0100
        Re: parent::__contruct() prima o dopo Alessandro Pellizzari <shuriken@amiran.it> - 2018-11-24 13:51 +0000
          Re: parent::__contruct() prima o dopo alex <1j9448a02@lnx159sneakemail.com.invalid> - 2018-11-24 16:04 +0100
            Re: parent::__contruct() prima o dopo Alessandro Pellizzari <shuriken@amiran.it> - 2018-11-25 11:12 +0000
              Re: parent::__contruct() prima o dopo alex <1j9448a02@lnx159sneakemail.com.invalid> - 2018-11-26 11:26 +0100
                Re: parent::__contruct() prima o dopo Alessandro Pellizzari <shuriken@amiran.it> - 2018-11-26 10:31 +0000
                  Re: parent::__contruct() prima o dopo alex <1j9448a02@lnx159sneakemail.com.invalid> - 2018-11-26 12:26 +0100
                    Re: parent::__contruct() prima o dopo Alessandro Pellizzari <shuriken@amiran.it> - 2018-11-26 11:45 +0000
                      Re: parent::__contruct() prima o dopo alex <1j9448a02@lnx159sneakemail.com.invalid> - 2018-11-26 13:02 +0100
                        Re: parent::__contruct() prima o dopo Alessandro Pellizzari <shuriken@amiran.it> - 2018-11-26 15:18 +0000
                          Re: parent::__contruct() prima o dopo Flavix <imeil@a.a> - 2018-11-26 17:03 +0100
                            Re: parent::__contruct() prima o dopo Alessandro Pellizzari <shuriken@amiran.it> - 2018-11-26 16:20 +0000
                              Re: parent::__contruct() prima o dopo off line <mail@inva.it> - 2018-11-27 08:25 +0100

#22357 — parent::__contruct() prima o dopo

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2018-11-23 08:51 +0100
Subjectparent::__contruct() prima o dopo
Message-ID<pt8bik$jv7$1@gioia.aioe.org>
class A extends B {
     private $_saveAs;

     function __construct1($saveAs, $wrapped) {
         $this->_saveAs = $saveAs;
         parent::__construct( $wrapped );
     }

     function __construct2($saveAs, $wrapped) {
         parent::__construct( $wrapped );
         $this->_saveAs = $saveAs;
     }
}

Quale dei due costruttori scegliere?

[toc] | [next] | [standalone]


#22360

FromAlessandro Pellizzari <shuriken@amiran.it>
Date2018-11-24 09:07 +0000
Message-ID<g5sin5Flg5vU2@mid.individual.net>
In reply to#22357
On 23/11/2018 07:51, alex wrote:

> class A extends B {
>      private $_saveAs;
> 
>      function __construct1($saveAs, $wrapped) {
>          $this->_saveAs = $saveAs;
>          parent::__construct( $wrapped );
>      }
> 
>      function __construct2($saveAs, $wrapped) {
>          parent::__construct( $wrapped );
>          $this->_saveAs = $saveAs;
>      }
> }
> 
> Quale dei due costruttori scegliere?

Evita l'ereditarietà, se puoi.

E poi scegli quello giusto per il caso d'uso. In Java sei obbligato a
chiamare parent() come prima cosa. In PHP hai flessibilità di farlo
dopo, quindi se settare _saveAs a un valore diverso può essere utile al
costruttore del genitore, usa la prima, altrimenti la seconda.

È comunque un code smell non indifferente. Probabilmente se lo stai
facendo c'è un modo migliore per fare la stessa cosa con codice più pulito.

Bye.

[toc] | [prev] | [next] | [standalone]


#22362

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2018-11-24 14:39 +0100
Message-ID<ptbka8$1uvd$1@gioia.aioe.org>
In reply to#22360
Il 24/11/18 10:07, Alessandro Pellizzari ha scritto:
> Evita l'ereditarietà, se puoi.
> 
> E poi scegli quello giusto per il caso d'uso. In Java sei obbligato a
> chiamare parent() come prima cosa. In PHP hai flessibilità di farlo
> dopo, quindi se settare _saveAs a un valore diverso può essere utile al
> costruttore del genitore, usa la prima, altrimenti la seconda.
> 
> È comunque un code smell non indifferente. Probabilmente se lo stai
> facendo c'è un modo migliore per fare la stessa cosa con codice più pulito.

interface Sender {
	/**
	 * Invia un'email.
	 */
	function send();
}

class SimpleSender implements Sender {
	function send() {
		//...
	}
}

abstract class AdvancedSender implements Sender {
	protected $_wrapped;

	public function __construct( Sender $wrapped ) {
		$this->_wrapped = $wrapped;
	}
}

class VerboseSender extends AdvancedSender {
	private $_verboseStream;

	public function __construct( $verboseStream, $wrapped ) {
		$this->_verboseStream = $verboseStream;
		parent::__construct( $wrapped );
	}

	function send() {
		$this->_verboseStream->write('Sto inviando un email...');
		$this->_wrapped->send();
	}
}

Tu come faresti?

[toc] | [prev] | [next] | [standalone]


#22363

FromAlessandro Pellizzari <shuriken@amiran.it>
Date2018-11-24 13:51 +0000
Message-ID<g5t3b2Fp484U1@mid.individual.net>
In reply to#22362
On 24/11/2018 13:39, alex wrote:

> interface Sender {
> 	function send();
> }
> 
> class SimpleSender implements Sender {
> 	function send() {

> abstract class AdvancedSender implements Sender {
> 	protected $_wrapped;
> 
> 	public function __construct( Sender $wrapped ) {
> 		$this->_wrapped = $wrapped;
> 	}
> }
> 
> class VerboseSender extends AdvancedSender {
> 	private $_verboseStream;
> 
> 	public function __construct( $verboseStream, $wrapped ) {
> 		$this->_verboseStream = $verboseStream;
> 		parent::__construct( $wrapped );
> 	}
> 
> 	function send() {
> 		$this->_verboseStream->write('Sto inviando un email...');
> 		$this->_wrapped->send();
> 	}
> }
> 
> Tu come faresti?

Perché AdvancedSender è abstract?

in VerboseSender inietti già un Sender ($wrapped) e lo decori. Non ti
serve estendere AdvancedSender. Puoi avere tre classi (SimpleSender,
AdvancedSender e VerboseSender) che implementano la stessa interfaccia
Sender ed eviti ereditarietà.

Bye.

[toc] | [prev] | [next] | [standalone]


#22364

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2018-11-24 16:04 +0100
Message-ID<ptbpir$all$1@gioia.aioe.org>
In reply to#22363
Il 24/11/2018 14:51, Alessandro Pellizzari ha scritto:
> in VerboseSender inietti già un Sender ($wrapped) e lo decori. Non ti
> serve estendere AdvancedSender. Puoi avere tre classi (SimpleSender,
> AdvancedSender e VerboseSender) che implementano la stessa interfaccia
> Sender ed eviti ereditarietà.

A questo punto elimino del tutto la classe AdvancedSender, però in ogni 
decoratore mi tocca incollare questa cosa:

	private $_wrapped;

	function __construct( Sender $wrapped ) {
		$this->_wrapped = $wrapped;
                 //...
	}

Volevo evitarlo.

[toc] | [prev] | [next] | [standalone]


#22365

FromAlessandro Pellizzari <shuriken@amiran.it>
Date2018-11-25 11:12 +0000
Message-ID<g5vecfFac48U2@mid.individual.net>
In reply to#22364
On 24/11/2018 15:04, alex wrote:

> in ogni
> decoratore mi tocca incollare questa cosa:
> 
> 	private $_wrapped;
> 
> 	function __construct( Sender $wrapped ) {
> 		$this->_wrapped = $wrapped;
>                  //...
> 	}

Un decoratore decora. Devi dirgli cosa decora... :)
PHP non ha una sintassi apposta per i decoratori. Il modo corretto è
proprio quello.

Tra l'altro quella è dependency injection, che va un casino negli ultimi
anni. :D

Bye.

[toc] | [prev] | [next] | [standalone]


#22366

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2018-11-26 11:26 +0100
Message-ID<ptghpd$1lg7$1@gioia.aioe.org>
In reply to#22365
Il 25/11/18 12:12, Alessandro Pellizzari ha scritto:
> Un decoratore decora. Devi dirgli cosa decora...:)
> PHP non ha una sintassi apposta per i decoratori. Il modo corretto è
> proprio quello.

E' quindi usare un decoratore astratto va bene?

[toc] | [prev] | [next] | [standalone]


#22367

FromAlessandro Pellizzari <shuriken@amiran.it>
Date2018-11-26 10:31 +0000
Message-ID<g620cvFrnu5U1@mid.individual.net>
In reply to#22366
On 26/11/2018 10:26, alex wrote:

> Il 25/11/18 12:12, Alessandro Pellizzari ha scritto:
>> Un decoratore decora. Devi dirgli cosa decora...:)
>> PHP non ha una sintassi apposta per i decoratori. Il modo corretto è
>> proprio quello.
> 
> E' quindi usare un decoratore astratto va bene?

Non capisco che utilità potrebbe avere, visto che poi devi istanziarlo, 
e non si può istanziare una classe astratta.

Bye.

[toc] | [prev] | [next] | [standalone]


#22368

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2018-11-26 12:26 +0100
Message-ID<ptgla2$1sd8$1@gioia.aioe.org>
In reply to#22367
Il 26/11/18 11:31, Alessandro Pellizzari ha scritto:
> On 26/11/2018 10:26, alex wrote:
> 
>> Il 25/11/18 12:12, Alessandro Pellizzari ha scritto:
>>> Un decoratore decora. Devi dirgli cosa decora...:)
>>> PHP non ha una sintassi apposta per i decoratori. Il modo corretto è
>>> proprio quello.
>>
>> E' quindi usare un decoratore astratto va bene?
> 
> Non capisco che utilità potrebbe avere, visto che poi devi istanziarlo, 
> e non si può istanziare una classe astratta.
> 
> Bye.


Eh?????????

Comunque ecco due link
https://code.tutsplus.com/tutorials/design-patterns-the-decorator-pattern--cms-22641

https://csharpcorner-mindcrackerinc.netdna-ssl.com/UploadFile/damubetha/decorator-pattern-in-csharp/Images/decorator.png

[toc] | [prev] | [next] | [standalone]


#22369

FromAlessandro Pellizzari <shuriken@amiran.it>
Date2018-11-26 11:45 +0000
Message-ID<g624nhFsmd0U1@mid.individual.net>
In reply to#22368
On 26/11/2018 11:26, alex wrote:

> Il 26/11/18 11:31, Alessandro Pellizzari ha scritto:

>> Non capisco che utilità potrebbe avere, visto che poi devi 
>> istanziarlo, e non si può istanziare una classe astratta.

> Eh?????????
> 
> Comunque ecco due link
> https://code.tutsplus.com/tutorials/design-patterns-the-decorator-pattern--cms-22641 

Che conferma quello che ho detto: non puoi istanziare la classe astratta.

Puoi avere una classe astratta per semplificare il wrapping nel caso 
base, ma è molto limitante. Cosa succede se devi passare altra roba al 
decoratore, invece che solo la classe decorata?

Il tuo codice richiede sia la classe wrappata che il $verboseStream, per 
esempio.

Per quello dico che non ha senso definire una classe astratta per il 
decoratore. L'articolo è del 2015, tra l'altro. Usa pesantemente 
l'ereditarietà anche quando non serve. Molto Java-inspired. :D

> https://csharpcorner-mindcrackerinc.netdna-ssl.com/UploadFile/damubetha/decorator-pattern-in-csharp/Images/decorator.png 

Questo a me pare abbastanza insulso, onestamente. C'è già un'interfaccia 
che il decoratore deve implementare. A cosa serve avere anche una classe 
astratta?

Forse dipende da limitazioni di C# o di Java, ma in PHP non ha proprio 
senso. Serve solo a rendere meno flessibile e più lento il codice.

Bye.

[toc] | [prev] | [next] | [standalone]


#22370

Fromalex <1j9448a02@lnx159sneakemail.com.invalid>
Date2018-11-26 13:02 +0100
Message-ID<ptgndd$mh$1@gioia.aioe.org>
In reply to#22369
Il 26/11/18 12:45, Alessandro Pellizzari ha scritto:
> On 26/11/2018 11:26, alex wrote:
> 
>> Il 26/11/18 11:31, Alessandro Pellizzari ha scritto:
> 
>>> Non capisco che utilità potrebbe avere, visto che poi devi 
>>> istanziarlo, e non si può istanziare una classe astratta.
> 
>> Eh?????????
>>
>> Comunque ecco due link
>> https://code.tutsplus.com/tutorials/design-patterns-the-decorator-pattern--cms-22641 
> 
> 
> Che conferma quello che ho detto: non puoi istanziare la classe astratta.

Ma penso che si possa istanziare una delle classi derivate, mi pare 
*super ovvio*.

> Puoi avere una classe astratta per semplificare il wrapping nel caso 
> base, ma è molto limitante. Cosa succede se devi passare altra roba al 
> decoratore, invece che solo la classe decorata?

Cioè?
Cmq un decoratore dovrebbe solo richiedere il $wrapper e nient'altro, o 
sbaglio?

> Il tuo codice richiede sia la classe wrappata che il $verboseStream, per 
> esempio.
> 
> Per quello dico che non ha senso definire una classe astratta per il 
> decoratore. L'articolo è del 2015, tra l'altro. Usa pesantemente 
> l'ereditarietà anche quando non serve. Molto Java-inspired. :D
> 
>> https://csharpcorner-mindcrackerinc.netdna-ssl.com/UploadFile/damubetha/decorator-pattern-in-csharp/Images/decorator.png 
> 
> 
> Questo a me pare abbastanza insulso, onestamente. C'è già un'interfaccia 
> che il decoratore deve implementare. A cosa serve avere anche una classe 
> astratta?

Ad evitare di ripetere questa cosa:

	private $wrapped;

	function __construct( Sender $wrapped ) {
		$this->wrapped = $wrapped;
	}

Mi sembra che l'avevo già scritto.

> Forse dipende da limitazioni di C# o di Java, ma in PHP non ha proprio 
> senso. Serve solo a rendere meno flessibile e più lento il codice.

Un esempio?

[toc] | [prev] | [next] | [standalone]


#22371

FromAlessandro Pellizzari <shuriken@amiran.it>
Date2018-11-26 15:18 +0000
Message-ID<g62h5bFssoU1@mid.individual.net>
In reply to#22370
On 26/11/2018 12:02, alex wrote:

> Cmq un decoratore dovrebbe solo richiedere il $wrapper e nient'altro, o 
> sbaglio?

Mi pare che abbiamo già avuto questa conversazione qualche mese fa...

Questo è il codice che hai scritto tu:

class VerboseSender extends AdvancedSender {
     private $_verboseStream;

     public function __construct( $verboseStream, $wrapped ) {
         $this->_verboseStream = $verboseStream;
         parent::__construct( $wrapped );
     }

     function send() {
         $this->_verboseStream->write('Sto inviando un email...');
         $this->_wrapped->send();
     }
}

Che, tra parentesi, trasformi in decoratore cambiando solo la prima riga

class VerboseSender implements Sender {
  ...
}

Questo è un decoratore, e prende $verboseStream, oltre a $wrapped.

>> A cosa serve avere 
>> anche una classe astratta?
> 
> Ad evitare di ripetere questa cosa:
> 
>      private $wrapped;
> 
>      function __construct( Sender $wrapped ) {
>          $this->wrapped = $wrapped;
>      }

> Mi sembra che l'avevo già scritto.

Sì, e io ripeto che mi sembra un motivo insulso.
Ci sono ben pochi decoratori che non hanno bsogno di altre informazioni 
oltre all'oggetto wrappato. Tipicamente fanno cose abbastanza basilari, 
tipo `toUpper`.

Ma se wrappi un oggetto tipicamente vuoi fare qualcosa di più, tipo, 
appunto, scrivere info aggiuntive in uno stream (e ti serve lo stream), 
personalizzare il comportamento in base a dati esterni (e ti serve una 
connessione al DB o un oggetto coi i dati da aggiungere), ecc.

In programmazione funzionale puoi fare currying del decoratore (in 
pratica generare dinamicamente un decoratore prima di applicarlo 
all'oggetto/funziona wrappata), ma in OOP devi passare roba al 
costruttore (o avere un DecoratorFactory... more Java! :P)

>> Forse dipende da limitazioni di C# o di Java, ma in PHP non ha proprio 
>> senso. Serve solo a rendere meno flessibile e più lento il codice.
> 
> Un esempio?

Vedi sopra.

Bye.

[toc] | [prev] | [next] | [standalone]


#22372

FromFlavix <imeil@a.a>
Date2018-11-26 17:03 +0100
Message-ID<pth5q3$ro7$1@gioia.aioe.org>
In reply to#22371
Il 26/11/2018 16:18, Alessandro Pellizzari ha scritto:
> Che, tra parentesi, trasformi in decoratore cambiando solo la prima riga
> 
> class VerboseSender implements Sender {
>   ...
> }

Scusate se mi intrometto, ma allora quello di alex cos'era?x
> Sì, e io ripeto che mi sembra un motivo insulso.
> Ci sono ben pochi decoratori che non hanno bsogno di altre informazioni 
> oltre all'oggetto wrappato. Tipicamente fanno cose abbastanza basilari, 
> tipo `toUpper`.
> 
> Ma se wrappi un oggetto tipicamente vuoi fare qualcosa di più, tipo, 
> appunto, scrivere info aggiuntive in uno stream (e ti serve lo stream), 
> personalizzare il comportamento in base a dati esterni (e ti serve una 
> connessione al DB o un oggetto coi i dati da aggiungere), ecc.
> 
> In programmazione funzionale puoi fare currying del decoratore (in 
> pratica generare dinamicamente un decoratore prima di applicarlo 
> all'oggetto/funziona wrappata), ma in OOP devi passare roba al 
> costruttore (o avere un DecoratorFactory... more Java! :P)

E qual'è il problema?

[toc] | [prev] | [next] | [standalone]


#22373

FromAlessandro Pellizzari <shuriken@amiran.it>
Date2018-11-26 16:20 +0000
Message-ID<g62kr8F1mpcU1@mid.individual.net>
In reply to#22372
On 26/11/2018 16:03, Flavix wrote:

> Il 26/11/2018 16:18, Alessandro Pellizzari ha scritto:
>> Che, tra parentesi, trasformi in decoratore cambiando solo la prima riga
>>
>> class VerboseSender implements Sender {
>>   ...
>> }
> 
> Scusate se mi intrometto, ma allora quello di alex cos'era?x

Vedi la discussione di qualche mese fa riguardo decoratori, wrapper, 
proxy, ecc. ecc.

Diversi nomi con minime differenze, ma il succo è lo stesso: wrappare un 
oggetto per fargli fare altre cose non previste senza dover modificare 
il codice originale.

Tecnicamente entrambi sono decoratori (mantengono la stessa interfaccia 
pubblica). Avere una classe astratta in mezzo non serve a niente.

>> In programmazione funzionale puoi fare currying del decoratore (in 
>> pratica generare dinamicamente un decoratore prima di applicarlo 
>> all'oggetto/funziona wrappata), ma in OOP devi passare roba al 
>> costruttore (o avere un DecoratorFactory... more Java! :P)
> 
> E qual'è il problema?

Sovraingegnerizzazione, che in questo caso, oltre a essere inutile, è 
anche dannosa (per le prestazioni e la flessibilità, oltre che per la 
pulizia del codice)

In Java viene parzialmente attenuato il problema, perché c'è una fase di 
compilazione, in cui l'optimizer potrebbe anche accorgersi che non usi 
mai alcuni percorsi della Factory, o che la classe astratta è 
piccolissima, e potrebbe decidere di mettere il codice inline, 
cancellando di fattola factory o l'abstract.

In PHP non c'è questa fase (anche perché PHP compila in millisecondi, 
mentre Java a volte impiega minuti), quindi ti becchi il problema a runtime.

Bye.

[toc] | [prev] | [next] | [standalone]


#22374

Fromoff line <mail@inva.it>
Date2018-11-27 08:25 +0100
Message-ID<ptirgi$1flv$1@gioia.aioe.org>
In reply to#22373
Il 26/11/18 17:20, Alessandro Pellizzari ha scritto:
>>
>> Scusate se mi intrometto, ma allora quello di alex cos'era?x
> 
> Vedi la discussione di qualche mese fa riguardo decoratori, wrapper, 
> proxy, ecc. ecc.

interesserebbe anche a me ma non la trovo

[toc] | [prev] | [standalone]


Back to top | Article view | it.comp.www.php


csiph-web