English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Questo articolo illustra un esempio di progettazione di pattern di programmazione Android: lo schema delle strategie. Lo condivido con tutti per riferimento, come segue:
Introduzione
In sviluppo software, si incontra spesso questo tipo di situazione: è possibile implementare una funzione con più algoritmi o strategie, e si scelgono diversi algoritmi o strategie in base alla situazione reale per completare la funzione. Ad esempio, gli algoritmi di ordinamento possono utilizzare l'ordinamento per inserimento, l'ordinamento per fusione, l'ordinamento per bolle, ecc.
Per questo tipo di situazione, un metodo comune è scrivere più algoritmi in una classe. Ad esempio, se è necessario fornire più algoritmi di ordinamento, questi algoritmi possono essere scritti in una classe, con ogni metodo che corrisponde a un algoritmo di ordinamento specifico: naturalmente, questi algoritmi di ordinamento possono anche essere encapsulati in un metodo unificato, utilizzando condizioni di giudizio come if...else... o case per scegliere l'algoritmo specifico. Questi due metodi di implementazione possono essere chiamati hardcoding. Tuttavia, quando molti algoritmi sono concentrati in una classe, questa classe diventa ingombrante, il costo di manutenzione della classe aumenta e è più facile introdurre errori durante la manutenzione. Se è necessario aggiungere un nuovo algoritmo di ordinamento, è necessario modificare il codice sorgente della classe di encapsulamento degli algoritmi. Questo chiaramente viola il principio OCP e il principio della responsabilità unica.
Se si astrae questi algoritmi o strategie e si fornisce un'interfaccia unificata, diversi algoritmi o strategie hanno diverse classi di implementazione. In questo modo, il client del programma può implementare la sostituzione dinamica degli algoritmi o delle strategie attraverso l'iniezione di diversi oggetti di implementazione. Questo schema ha una maggiore estensibilità e mantenibilità, che è anche ciò che stiamo dicendo nel nostro capitolo: lo schema delle strategie.
In sintesi, di solito, se un problema ha più soluzioni, la più semplice è utilizzare il metodo if-else o switch-case per scegliere la soluzione diversa in base alla situazione, ma in questo modo la coesione è troppo alta, il codice è ingombrante e difficile da mantenere. In questo caso, si può utilizzare lo schema delle strategie per risolvere il problema.
II. Definizione
Lo schema delle strategie definisce una serie di algoritmi, incapsula ciascun algoritmo e li rende intercambiabili. Lo schema delle strategie rende l'algoritmo indipendente dal cliente che lo utilizza e lo rende indipendente dalle variazioni.
III. Scenari d'uso
Per diversi modi di trattare lo stesso tipo di problema, quando le differenze sono solo nelle azioni concrete
Quando è necessario incapsulare in modo sicuro più operazioni dello stesso tipo
Quando ci sono più sottoclassi della stessa classe astratta e si deve utilizzare if-else o switch-case per selezionare la sottoclasse specifica
IV. Diagramma UML dello schema delle strategie
Diagramma UML:
Context: ambiente di operazione per le strategie.
Stragety: astrazione delle strategie.
ConcreteStrategyA, ConcreteStrategyB: implementazioni concrete delle strategie.
V. Implementazione semplice
Richiesta: calcolare il prezzo dei libri, i membri principianti non hanno sconti, i membri intermedi hanno il 10% di sconto, i membri premium hanno l'8% di sconto. Se si utilizza la scrittura tradizionale, dovrebbe essere un controllo if-else per determinare il livello del membro e calcolare il sconto corrispondente. Di seguito viene utilizzato lo schema delle strategie per implementarlo.
Classe astratta di sconto:
public interface MemberStrategy { /** * Calcolare il prezzo del libro * @param booksPrice Prezzo originale del libro * @return Calcolare il prezzo scontato */ public double calcPrice(double booksPrice); }
Classe di sconto per membri principianti:
public class PrimaryMemberStrategy implements MemberStrategy{ /** * Sconto per membri principianti */ @Override public double calcPrice(double booksPrice) { System.out.println("Per i membri principianti non ci sono sconti"); return booksPrice; } }
Classe di sconto per membri intermedi:
public class IntermediateMemberStrategy implements MemberStrategy{ /** * Sconto per membri intermedi */ @Override public double calcPrice(double booksPrice) { System.out.println("Per i membri intermedi la sconto è del 10%"); return booksPrice * 0.9; } }
Classe di sconto per membri premium:
public class AdvancedMemberStrategy implements MemberStrategy{ /** * Sconto per membri premium */ @Override public double calcPrice(double booksPrice) { System.out.println("Per i membri premium la sconto è del 20%"); return booksPrice * 0.8; } }
Classe del prezzo:
public class Price { //Mantenere un oggetto strategia specifico private MemberStrategy strategy; /** * Costruttore, passare un oggetto strategia specifico * @param strategy Oggetto strategia specifico */ public Price(MemberStrategy strategy){ this.strategy = strategy; } /** * Calcolare il prezzo del libro * @param booksPrice Prezzo originale del libro * @return Calcolare il prezzo scontato */ public double quote(double booksPrice){ return this.strategy.calcPrice(booksPrice); } }
Client:
public class Client { public static void main(String[] args) { //Creare l'oggetto strategia necessario //Scegliere e creare l'oggetto strategia necessario //Creazione dell'ambiente Price price = new Price(strategy1); //Calcolo del prezzo double quote = price.quote(300); System.out.println("Il prezzo finale del libro è: " + quote); } }
Risultato:
La sconto per i membri premium è del 20% Il prezzo finale del libro è: 240.0
Sesto, differenza tra il pattern di strategia e il pattern di fabbrica
Pattern di fabbrica | Pattern di strategia |
---|---|
Pattern di design di creazione | Pattern di design comportamentale |
Prendere in considerazione la creazione degli oggetti | Prendere in considerazione la scelta del comportamento |
Scatola nera (non è necessario sapere il processo di implementazione specifico) | Scatola bianca (conoscere il processo di implementazione specifico) |
Settimo, implementazione del pattern di strategia nel codice sorgente di Android
Con lo sviluppo della tecnologia, gli ingegneri prestano sempre più attenzione all'esperienza utente e all'interazione utente. Pertanto, l'animazione è diventata una parte essenziale di molte applicazioni, persino una pagina di guida semplice deve essere fatta con un effetto animato, e persino l'oscuramento di un pulsante richiede l'aggiunta di un effetto di dissolvenza. Il principio di realizzazione dell'animazione è eseguire rapidamente il cambiamento delle immagini in breve tempo, la frequenza di questo cambiamento deve raggiungere un livello che l'occhio umano non percepisca il lag, ad esempio, il film standard è 24 fotogrammi al secondo. Quando è molto fluido, l'animazione su Android può raggiungere 60 fotogrammi al secondo, l'occhio umano non percepisce l'intervallo, quindi, vediamo questa animazione come molto fluida.
Un'animazione semplice non è sufficiente a soddisfare le nostre esigenze. Durante l'esecuzione dell'animazione, abbiamo bisogno di alcuni effetti dinamici, che sono simili ai ritardi della telecamera lenta nei film. A volte dobbiamo rallentare, altre volte accelerare, in modo che l'animazione diventi più vivace. Questi effetti dinamici sono realizzati tramite interpolatori (TimeInterpolator), e possiamo ottenere diversi effetti dinamici semplicemente configurando diversi interpolatori per l'oggetto Animation.
LinearInterpolator, AccelerateInterpolator, CycleInterpolator e altri implementano Interpolator, tramite getInterpolator(float input) per ottenere la percentuale di tempo corrente, in modo da calcolare il valore dell'attributo dell'animazione.
Capitolo 8: Conclusione
Il modello di strategia viene principalmente utilizzato per separare gli algoritmi, con diverse implementazioni specifiche under la stessa astrazione comportamentale. Questo modello dimostra chiaramente il principio di chiusura aperta, ovvero definire l'astrazione e iniettare diverse implementazioni per ottenere una buona estensibilità.
Vantaggi:
La struttura è chiara e intuitiva.
La coesione è relativamente bassa e l'espansione è facile.
L'encapsulation operativa è più completa e i dati sono più sicuri.
Svantaggi:
Con l'aumento delle strategie, il numero di sottoclassi aumenta anche.
Chi è interessato a ulteriori contenuti relativi a Android può consultare le sezioni speciali del nostro sito: 'Tutorial di avvio e avanzamento per lo sviluppo Android', 'Tecniche di debug e soluzioni ai problemi comuni di Android', 'Sommarizzazione dell'uso dei componenti di base di Android', 'Sommarizzazione delle tecniche di View di Android', 'Sommarizzazione delle tecniche di layout di Android' e 'Sommarizzazione dell'uso dei controlli di Android'.
Spero che il contenuto di questo articolo possa essere utile per la progettazione di applicazioni Android.
Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, è di proprietà del rispettivo autore. Il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, il sito web non detiene il diritto di proprietà, non è stato editato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, sei invitato a inviare una email a: notice#oldtoolbag.com (al momento dell'invio dell'email, sostituisci # con @) per segnalare il problema, fornendo prove pertinenti. Una volta verificata, il sito eliminerà immediatamente il contenuto sospetto di violazione del copyright.