Newsgroup: it.comp.www.php
Titolo: parent::__contruct() prima o dopo

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.
 
 

 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?

 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.

 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.

 	}
 
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.
 

 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.

Il 26/11/18 11:31, Alessandro Pellizzari ha scritto:

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
 

 
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.

 senso. Serve solo a rendere meno flessibile e più lento il codice.
 
Un esempio?

 Un esempio?
 
Vedi sopra.
 
Bye.

 costruttore (o avere un DecoratorFactory... more Java! :P)
 
E qual'è il problema?

 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.
 

 proxy, ecc. ecc.
 
interesserebbe anche a me ma non la trovo