Nel solito schema di strategia, facciamo ogni strategia come una classe. Non possiamo renderlo una funzione, e basta assegnare il riferimento alla funzione quando istanziamo un oggetto e lascia che l'oggetto chiami quella funzione?In Strategy Pattern, non possiamo rendere ogni strategia come una funzione ma non come una classe?
In Strategy Pattern, non possiamo rendere ogni strategia come una funzione ma non come una classe?
risposta
Nei casi più semplici, è possibile sostituire i modelli di strategia con un puntatore a funzione. Tuttavia, considerare questo caso
class HourlyPayStrategy implements PayStrategy
{
public int calculate()
{
int x = doComplexOperation1();
int y = doComplexOperation2();
return x + y;
}
private int doComplexOperation1()
{
// ...
}
private int doComplexOperation2()
{
// ...
}
}
Se abbiamo appena dato un semplice puntatore a funzione, le cose iniziano diventando davvero pelose, perché non è più possibile refactoring quella cosa (beh, almeno non in modo ben incapsulata).
Non sono d'accordo. Se fai riferimento a HourlyPayStrategy o HourlyPayStrategy.calculate non fa differenza in termini di refactoring o incapsulamento. –
@DavidArno con la tua notazione Credo che tu conosca C#, che fa un buon lavoro eseguendo _eta expansion_. Questa notazione non è affatto facile da ottenere in molte lingue: JavaScript, Ruby, Python, Java, OCaml anche (parlando da una memoria vecchia di anni), C++ (domande: come si ciba ora C++ 11 al giorno d'oggi?). – kizzx2
In molte lingue, quando ci si aspetta un parametro _function_ come parametro, è abbastanza diverso da aspettarsi un _method_, dove il compilatore/runtime dovrebbe portare con sé l'oggetto associato. Quindi sì, per C# il tuo argomento ha le gambe. – kizzx2
Dipende dalla lingua. In C# potresti renderlo un delegato. In Java, sarebbe piuttosto una classe anonima. In C++, potresti davvero renderlo un puntatore a funzione.
Certo, anche se utilizzando gli oggetti è possibile sfruttare l'ereditarietà in modi che non si possono ottenere con le sole funzioni.
In C# è possibile utilizzare i delegati con il modello di strategia. Date un'occhiata a questo blog post per un esempio.
Cosa succede sotto il cofano nella maggior parte delle implementazioni C++ è quasi quello che suggerisci. Il compilatore di solito risolve una Strategy.virtualMethod call() come questo (in pseudo codice):
(Strategy.pVtable[indexOfVirtualMethod])()
Quindi, se la vostra unica preoccupazione è quella più dereferenziazione di un puntatore (pVtable) si dovrebbe davvero profilo in primo luogo se non è possibile identificare gli hotspot più gravi.
La mia sensazione è che il codice sarà molto più difficile da capire e mantenere quando si utilizza un puntatore a funzione invece di un oggetto strategia.
- 1. Come implementare Strategy Pattern in Go?
- 2. Rendere una classe non ereditata
- 3. Posso rendere una classe non sigillata internamente ma sigillata esternamente?
- 4. Design Patterns - Strategy Pattern
- 5. Rendere visibile una proprietà in DataGridView ma NON in PropertyGrid?
- 6. : hover ma: non su una classe specifica
- 7. Rendere una variabile globale accessibile per ogni funzione all'interno di una classe
- 8. Schema di strategia in Python quando una "strategia" consiste in più di una funzione
- 9. Come creare una classe che sia astratta, ma non internamente
- 10. Come associare pattern a una classe nidificata in Scala?
- 11. Come rendere una classe interna Parcelable
- 12. Come rendere QCheckBox in sola lettura, ma non in grigio
- 13. Come possiamo chiamare una funzione con "parametro = valore" in C++?
- 14. Come si esegue una funzione ogni secondo
- 15. Possiamo dichiarare una funzione amico senza argomento?
- 16. Posso passare un pattern in una funzione?
- 17. come dire una variabile è iterabile ma non una stringa
- 18. Come rendere una classe Thread Safe
- 19. Puoi creare un'istanza di una classe non per un tipo ma per un'intera classe in Haskell?
- 20. Possiamo definire enum all'interno di una funzione?
- 21. pattern.test non è una funzione
- 22. Perché puoi istanziare una classe da una variabile stringa ma non una stringa in PHP?
- 23. Python: __str__, ma per una classe, non un'istanza?
- 24. Riesci a rendere un metodo di una classe non ereditabile?
- 25. Come eseguire una funzione in ogni pagina in AngularJs
- 26. Come si include una classe UX nel pattern MVC?
- 27. Come rendere mobile/trascinabile una finestra non decorata in JavaFX?
- 28. Come posso rendere una funzione definita in jQuery.ready disponibile globalmente?
- 29. Come associare funzioni non membri a una classe in Doxygen?
- 30. Costruire una nuova strategia per Omniauth, ma Omniauth non la trova
Divertiti con Java in questo caso :) – Joey
perché? Java non supporta il riferimento alla funzione? –
+1 per pensare in modo critico a Design Patterns. Direi che molti modelli di design derivano dalla radice dell'incapacità della lingua. Quindi in molti casi, i modelli di progettazione non sono bibbie :) – kizzx2