Exemple du modèle de stratégie dans le monde réel
j'ai lu à propos du principal OCP et comment utiliser le modèle de stratégie pour accomplir ceci.
j'allais essayer d'expliquer cela à quelques personnes, mais le seul exemple que je puisse imaginer est l'utilisation de différentes classes de validation basées sur le statut d'un" ordre".
j'ai lu quelques articles en ligne, mais ceux-ci ne décrivent généralement pas une véritable raison d'utiliser la stratégie, comme générer rapports/factures/validation etc...
y a-t-il des exemples dans le monde réel où vous pensez qu'un schéma de stratégie est commun?
16 réponses
Qu'à ce sujet:
vous devez crypter un fichier.
pour les petits fichiers, vous pouvez utiliser la stratégie "en mémoire", où le fichier complet est lu et conservé en mémoire ( disons pour les fichiers < 1 Go)
pour les gros fichiers, vous pouvez utiliser une autre stratégie, où des parties du fichier sont lues en mémoire et les résultats partiellement chiffrés sont stockés dans des fichiers tmp.
il peut s'agir de deux stratégies différentes pour même tâche.
le code client serait le même:
File file = getFile();
Cipher c = CipherFactory.getCipher( file.size() );
c.performAction();
// implementations:
interface Cipher {
public void performAction();
}
class InMemoryCipherStrategy implements Cipher {
public void performAction() {
// load in byte[] ....
}
}
class SwaptToDiskCipher implements Cipher {
public void performAction() {
// swapt partial results to file.
}
}
le
Cipher c = CipherFactory.getCipher( file.size() );
retournerait l'instance de stratégie correcte pour le cipher.
j'espère que cela aidera.
(Je ne sais même pas si Cipher est le mot juste :P )
encore une fois, un ancien post mais apparaît toujours sur les recherches donc je vais ajouter deux autres exemples (le Code est en C#). J'adore le modèle de Stratégie, car il a sauvé mes fesses beaucoup de moments où les gestionnaires de projet, dire: "Nous voulons l'application à faire "X", mais " X " n'est pas encore clair et il peut changer dans un avenir proche." Cette vidéo expliquant le schéma de stratégie , utilise StarCraft comme exemple.
matière qui tombe dans cette catégorie:
-
Tri: nous voulons trier ces nombres, mais nous ne savons pas si nous allons utiliser BrickSort, BubbleSort ou un autre tri
-
Validation: nous avons besoin de vérifier les éléments selon "une certaine règle", mais il n'est pas encore clair ce que sera cette règle, et nous pouvons penser à de nouvelles.
-
jeux: nous voulons que le joueur soit marcher ou courir quand il bouge, mais peut-être dans le futur, il devrait également être capable de nager, voler, se téléporter, enfouir sous terre, etc.
-
stocker l'information: nous voulons que l'application pour stocker l'information à la base de données, mais plus tard, il peut avoir besoin de pouvoir enregistrer un fichier, ou faire une webcall
-
Outputting: nous avons besoin de produire X comme une chaîne simple, mais plus tard peut être un CSV, XML, JSON, etc.
exemples
j'ai un projet où les utilisateurs peuvent assigner des produits aux personnes dans une base de données. Cette cession d'un produit à une personne a un statut "Approuvé" ou "refusé", qui dépend de certaines règles commerciales. Par exemple: si un utilisateur assigne un produit à une personne ayant un certain âge, son statut doit être refusé; si la différence entre deux champs de l'article est supérieure à 50, son statut est refusé, etc.
maintenant, au moment du développement ces règles d'affaires ne sont pas encore tout à fait claires, et de nouvelles règles pourraient apparaître à tout moment. Le pouvoir du stragety-pattern est que j'ai fait un Régleagent, qui est donné une liste d'IRules.
public interface IRule {
bool IsApproved(Assignment assignment);
}
au moment d'assigner un produit à une personne, je crée un Régleagent, je lui donne une liste de règles (qui toutes implémentent IRule), et je lui demande de valider une assignation. Ça passera par toutes les règles. Qui, parce qu'ils implémentent la même interface, tous ont le IsApproved
méthode et retourne false si l'un d'eux retourne false.
maintenant, par exemple, quand le directeur se présente soudainement et dit, nous devons également refuser toutes les affectations à des stagiaires, ou toutes les affectations à des personnes travaillant des heures supplémentaires... Vous faites de nouvelles classes comme celle-ci:
public OvertimeRule : IRule
{
public bool IsApproved(Assignment assignment) //Interface method
{
if (assignment.Person.Timesheet >= 40)
{
return false;
}
return true;
}
}
public InternRule : IRule
{
public bool IsApproved(Assignment assignment) //Interface method
{
if (assignment.Person.Title == "Intern")
{
return false;
}
return true;
}
}
vous voyez que vous ne devez pas continuer à ajouter ou supprimer si-déclarations ou code, il suffit de faire une nouvelle règle-classe qui met en œuvre l'interface IRUle et de passer ces derniers en cas de besoin.
un Autre excellent exemple: Scott Allen, une série vidéo http://www.asp.net/mvc/pluralsight où il utilise le modèle de stratégie dans l'Unité-partie de test de l'application
il construit un site web qui a une page qui affiche des éléments basés sur la popularité. Cependant "populaire" peut être beaucoup de choses (la plupart des points de vue, la plupart des abonnés, date de création, la plupart des activités, le moins de commentaires, etc), et dans le cas où la gestion ne sait pas encore exactement comment commander, et peut vouloir expérimenter avec différentes commandes à une date ultérieure. Vous faites une interface (IOrderAlgorithm ou quelque chose) avec une méthode de commande, et laissez un Orderer-object déléguer la commande à une implémentation concrète de l'interface IOrderAlgorithm. Vous pouvez faire un "CommentOrderer", "ActivityOrderer", etc... Et changez - les quand de nouvelles exigences apparaissent.
je peux penser à plusieurs exemples assez simples:
- Tri d'une liste. La stratégie est la comparaison utilisée pour décider lequel des deux éléments dans la liste est "d'Abord",
- vous pourriez avoir une application où l'algorithme de tri lui-même (QuickSort, Hapsort, etc.) peut être choisi à l'exécution
- Appenders, Mises en page, des Filtres et des Log4Net et Log4j
- Gestionnaires de Disposition dans l'INTERFACE utilisateur de boîtes à outils
-
compression de données. Vous avez peut-être une interface ICompressor dont la seule méthode ressemble à quelque chose comme ceci:
byte[] compresser(byte[] input);
vos classes de compression de béton peuvent être des choses comme la compression de durée de vie, la compression de durée de vie, etc.
une utilisation courante du pattern de stratégie est de définir des stratégies de tri personnalisées (dans des langues sans fonctions d'ordre supérieur), par exemple pour trier une liste de chaînes par longueur en Java, en passant une classe interne anonyme (une implémentation de l'interface de stratégie):
List<String> names = Arrays.asList("Anne", "Joe", "Harry");
Collections.sort(names, new Comparator<String>() {
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
});
Assert.assertEquals(Arrays.asList("Joe", "Anne", "Harry"), names);
de la même manière, des stratégies peuvent être utilisées pour les requêtes natives avec des bases de données d'objets, p.ex. dans db4o:
List<Document> set = db.query(new Predicate<Document>() {
public boolean match(Document candidate) {
return candidate.getSource().contains(source);
}
});
j'ai une application qui synchronise sa base d'utilisateurs Chaque jour avec notre répertoire d'entreprise. Les utilisateurs sont admissibles ou non, selon leur statut à l'Université. Chaque jour le programme d'approvisionnement passe et s'assure que ceux qui sont censés être éligibles sont fournis dans l'application et ceux qui ne sont pas fournis (en fait selon un algorithme de dégradation gracieuse, mais ce n'est pas le point). Le samedi je fais un plus complet mise à jour qui synchronise certaines propriétés de chaque utilisateur ainsi que de s'assurer qu'ils ont le bon d'admissibilité. À la fin du mois, je fais un peu de traitement de facture basé sur l'utilisation pour ce mois.
j'utilise un modèle de stratégie composable pour faire cette synchronisation. Le programme principal choisit essentiellement une stratégie de master en fonction du jour de la semaine (sync change only/sync all) et du moment du semestre par rapport au calendrier académique. Si le cycle de facturation est il se termine, puis il le compose également avec une stratégie de facturation. Il exécute ensuite la stratégie choisie via une interface standard.
je ne sais pas comment c'est, mais je sentais que c'était un ajustement parfait pour le modèle de stratégie.
"151930920 Clés", notes:
-
stratégie est un modèle de conception comportementale. Il est utilisé pour basculer entre la famille d'algorithmes.
-
Ce modèle contient une stratégie Abstraite interface et beaucoup béton implémentations de stratégie ( algorithmes ) de cette interface.
-
l'application utilise la stratégie interface seulement. En fonction de certains paramètres de configuration, le stratégie concrète sera étiqueté interface .
UML diagramme de wikipedia
Un vrai mot exemple : les Compagnies aériennes offrent des rabais pendant quelques mois (juillet-décembre) . Vous pouvez avoir un tarif module, qui décide des options de prix en fonction du nombre de mois.
regardez un exemple simple. Cet exemple peut être étendu aux applications de vente au détail en ligne, qui offre des rabais sur les articles de panier lors de jours spéciaux / happy hours facilement.
import java.util.*;
/* Interface for Strategy */
interface OfferStrategy {
public String getName();
public double getDiscountPercentage();
}
/* Concrete implementation of base Strategy */
class NoDiscountStrategy implements OfferStrategy{
public String getName(){
return this.getClass().getName();
}
public double getDiscountPercentage(){
return 0;
}
}
/* Concrete implementation of base Strategy */
class QuarterDiscountStrategy implements OfferStrategy{
public String getName(){
return this.getClass().getName();
}
public double getDiscountPercentage(){
return 0.25;
}
}
/* Context is optional. But if it is present, it acts as single point of contact
for client.
Multiple uses of Context
1. It can populate data to execute an operation of strategy
2. It can take independent decision on Strategy creation.
3. In absence of Context, client should be aware of concrete strategies. Context acts a wrapper and hides internals
4. Code re-factoring will become easy
*/
class StrategyContext {
double price; // price for some item or air ticket etc.
Map<String,OfferStrategy> strategyContext = new HashMap<String,OfferStrategy>();
StrategyContext(double price){
this.price= price;
strategyContext.put(NoDiscountStrategy.class.getName(),new NoDiscountStrategy());
strategyContext.put(QuarterDiscountStrategy.class.getName(),new QuarterDiscountStrategy());
}
public void applyStrategy(OfferStrategy strategy){
/*
Currently applyStrategy has simple implementation. You can use Context for populating some more information,
which is required to call a particular operation
*/
System.out.println("Price before offer :"+price);
double finalPrice = price - (price*strategy.getDiscountPercentage());
System.out.println("Price after offer:"+finalPrice);
}
public OfferStrategy getStrategy(int monthNo){
/*
In absence of this Context method, client has to import relevant concrete Strategies everywhere.
Context acts as single point of contact for the Client to get relevant Strategy
*/
if ( monthNo < 6 ) {
return strategyContext.get(NoDiscountStrategy.class.getName());
}else{
return strategyContext.get(QuarterDiscountStrategy.class.getName());
}
}
}
public class StrategyDemo{
public static void main(String args[]){
StrategyContext context = new StrategyContext(100);
System.out.println("Enter month number between 1 and 12");
int month = Integer.parseInt(args[0]);
System.out.println("Month ="+month);
OfferStrategy strategy = context.getStrategy(month);
context.applyStrategy(strategy);
}
}
sortie:
Enter month number between 1 and 12
Month =1
Price before offer :100.0
Price after offer:100.0
Enter month number between 1 and 12
Month =7
Price before offer :100.0
Price after offer:75.0
articles utiles:
stratégie modèle par dzone
stratégie modèle par sourcemaking
je sais que c'est une vieille question, mais je pense que j'ai un autre exemple intéressant que j'ai mis en œuvre récemment.
il s'agit d'un exemple très pratique du modèle de stratégie utilisé dans un système de fourniture de documents.
j'ai eu un système de livraison PDF qui a reçu une archive contenant beaucoup de documents et quelques métadonnées. En se basant sur les métadonnées, il a décidé où placer le document; disons, selon les données, je pourrais stocker le document en A
, B
, ou C
systèmes de stockage, ou un mélange des trois.
différents clients ont utilisé ce système, et ils ont eu différentes exigences de roll-back / erreur de traitement en cas d'erreurs: l'un voulait que le système de livraison s'arrête sur la première erreur, laisser tous les documents déjà livrés dans leurs stockages, mais arrêter le processus et ne pas livrer quoi que ce soit d'autre; un autre voulait qu'il recule de B
en cas d'erreurs lors du stockage dans C
, mais laisser ce qui a déjà été livré à A
. Il est facile d'imaginer qu'un troisième ou un quatrième va également avoir des besoins différents.
pour résoudre le problème, j'ai créé une classe de livraison de base qui contient la logique de livraison, ainsi que des méthodes pour récupérer les choses de tous les magasins. Ces méthodes ne sont pas directement appelées par le système de livraison en cas d'erreurs. Au lieu de cela, la classe utilise L'Injection de dépendances pour recevoir un "Rollback" / Classe de stratégie de traitement des erreurs" (basé sur le client utilisant le système), qui est appelé en cas d'erreurs, qui à son tour appelle les méthodes de rollback si elle est appropriée pour cette stratégie.
la classe de livraison elle-même fait rapport de ce qui se passe à la classe de stratégie (quels documents ont été livrés à quels stocks, et quels échecs se sont produits), et chaque fois qu'une erreur se produit, elle demande à la stratégie de continuer ou non. Si la stratégie dit "stop it", la classe appelle le la méthode de "nettoyage" de la stratégie, qui utilise les informations précédemment rapportées pour décider quelles méthodes de retour en arrière appeler de la classe de livraison, ou tout simplement ne rien faire.
rollbackStrategy.reportSuccessA(...);
rollbackStrategy.reportFailureB(...);
if (rollbackStrategy.mustAbort()) {
rollbackStrategy.rollback(); // rollback whatever is needed based on reports
return false;
}
donc j'ai maintenant deux stratégies différentes: l'une est le QuitterStrategy
(qui quitte sur la première erreur et ne nettoie rien) et l'autre est le MaximizeDeliveryToAStrategy
(qui essaie autant que possible de ne pas avorter le processus et ne jamais faire reculer la substance livrée au stockage A
, mais le matériel de rappel de B
si la livraison à C
échoue).
d'après ce que j'ai compris, ceci est un exemple du schéma stratégique. Si vous (oui, vous lisez) pensez que je me trompe, s'il vous plaît commentaire ci-dessous et me faire savoir. Je suis curieux de savoir ce qui constituerait une utilisation "pure" du modèle de stratégie, et quels aspects de ma mise en œuvre violent la définition. Je pense que ça a l'air un peu drôle parce que l'interface de stratégie est un peu grosse. Tous les exemples que j'ai vu utiliser jusqu'à présent seulement une méthode, mais je pense toujours que cela encapsule un algorithme (si un morceau de logique d'affaires peut être considéré un algorithme, ce que je pense qu'il fait).
étant donné que la stratégie est également informée des événements pendant l'exécution de la livraison, elle peut également être considérée comme un Observateur , mais c'est une autre histoire.
de faire un peu de recherche, il semble que ce soit un "modèle composite" (comme MVC, un modèle qui utilise plusieurs les modèles de conception en dessous d'une certaine façon) appelé le Conseiller . C'est un conseiller sur la poursuite ou non de la livraison, mais c'est aussi un gestionnaire d'erreurs actif car il peut faire reculer des choses lorsqu'on le lui demande.
quoi qu'il en soit, c'est un exemple assez complexe qui pourrait rendre votre sentiment que les usages du schéma de stratégie sont trop simples / stupides. Il peut être très complexe et encore plus nécessaire lorsqu'il est utilisé conjointement avec d'autres modèle.
pattern de stratégie est le plus couramment utilisé pattern spécialement pour les validations et les algorithmes de tri.
permettez-moi d'expliquer avec un exemple pratique simple
enum Speed {
SLOW, MEDIUM, FAST;
}
class Sorter {
public void sort(int[] input, Speed speed) {
SortStrategy strategy = null;
switch (speed) {
case SLOW:
strategy = new SlowBubbleSortStrategy();
break;
case MEDIUM:
strategy = new MediumInsertationSortStrategy();
break;
case FAST:
strategy = new FastQuickSortStrategy();
break;
default:
strategy = new MediumInsertationSortStrategy();
}
strategy.sort(input);
}
}
interface SortStrategy {
public void sort(int[] input);
}
class SlowBubbleSortStrategy implements SortStrategy {
public void sort(int[] input) {
for (int i = 0; i < input.length; i++) {
for (int j = i + 1; j < input.length; j++) {
if (input[i] > input[j]) {
int tmp = input[i];
input[i] = input[j];
input[j] = tmp;
}
}
}
System.out.println("Slow sorting is done and the result is :");
for (int i : input) {
System.out.print(i + ",");
}
}
}
class MediumInsertationSortStrategy implements SortStrategy {
public void sort(int[] input) {
for (int i = 0; i < input.length - 1; i++) {
int k = i + 1;
int nxtVal = input[k];
while (input[k - 1] > nxtVal) {
input[k] = input[k - 1];
k--;
if (k == 0)
break;
}
input[k] = nxtVal;
}
System.out.println("Medium sorting is done and the result is :");
for (int i : input) {
System.out.print(i + ",");
}
}
}
class FastQuickSortStrategy implements SortStrategy {
public void sort(int[] input) {
sort(input, 0, input.length-1);
System.out.println("Fast sorting is done and the result is :");
for (int i : input) {
System.out.print(i + ",");
}
}
private void sort(int[] input, int startIndx, int endIndx) {
int endIndexOrig = endIndx;
int startIndexOrig = startIndx;
if( startIndx >= endIndx)
return;
int pavitVal = input[endIndx];
while (startIndx <= endIndx) {
while (input[startIndx] < pavitVal)
startIndx++;
while (input[endIndx] > pavitVal)
endIndx--;
if( startIndx <= endIndx){
int tmp = input[startIndx];
input[startIndx] = input[endIndx];
input[endIndx] = tmp;
startIndx++;
endIndx--;
}
}
sort(input, startIndexOrig, endIndx);
sort(input, startIndx, endIndexOrig);
}
}
le code d'essai est
public class StrategyPattern {
public static void main(String[] args) {
Sorter sorter = new Sorter();
int[] input = new int[] {7,1,23,22,22,11,0,21,1,2,334,45,6,11,2};
System.out.print("Input is : ");
for (int i : input) {
System.out.print(i + ",");
}
System.out.println();
sorter.sort(input, Speed.SLOW);
}
}
le même exemple est tiré de http://coder2design.com/strategy-pattern/
un bon exemple de modèle de stratégie serait dans un jeu où nous pouvons avoir des caractères différents et chaque caractère peut avoir plusieurs armes à attaquer, mais à la fois ne peut utiliser qu'une seule arme. Nous avons donc le caractère comme contexte, par exemple Roi, Commandeur, Chevalier, soldat et l'arme comme une stratégie d'attaque() pourrait être la méthode/de l'algorithme qui dépend des armes utilisées. Ainsi, si les classes d'armes en béton étaient L'épée, La Hache, L'arbalète, le BowAndArrow, etc.. ils seraient tous mettre en œuvre l'attaque (). Je suis sûr que d'autres explications ne sont pas nécessaires.
Êtes-vous sûr que le statut d'un "ordre" n'est pas un État modèle? J'ai le pressentiment qu'une commande ne sera pas traitée différemment selon son statut.
prendre par exemple la méthode Ship sur l'ordre:
order.Ship();
- si la méthode d'expédition varie en fonction de son statut, alors vous avez a un modèle de stratégie.
- si toutefois la méthode Ship () réussit seulement lorsque la commande a été payée, et la commande n'a pas encore été expédiées, vous avez un état de modèle.
le meilleur exemple du modèle d'état (et d'autres modèles) que j'ai trouvé était dans le livre " Head First Design Patterns ", ce qui est étonnant. La seconde sera , la série de blogs de David Cumps .
disons que vous voulez écrire un algorithme pour calculer le nth Xday d'un mois et d'une année donnés, par exemple, le deuxième lundi d'octobre 2014. Vous voulez utiliser la classe de temps D'Android android.text.format.Time
pour représenter la date, mais vous voulez également écrire un algorithme générique qui peut également s'appliquer à java.util.Calendar
.
C'est ce que j'ai fait.
Dans DatetimeMath.java:
public interface DatetimeMath {
public Object createDatetime(int year, int month, int day);
public int getDayOfWeek(Object datetime);
public void increment(Object datetime);
}
In TimeMath.Java:
public class TimeMath implements DatetimeMath {
@Override
public Object createDatetime(int year, int month, int day) {
Time t = new Time();
t.set(day, month, year);
t.normalize(false);
return t;
}
@Override
public int getDayOfWeek(Object o) {
Time t = (Time)o;
return t.weekDay;
}
@Override
public void increment(Object o) {
Time t = (Time)o;
t.set(t.monthDay + 1, t.month, t.year);
t.normalize(false);
}
}
Dans OrdinalDayOfWeekCalculator.java, la classe avec l'algorithme générique:
public class OrdinalDayOfWeekCalculator {
private DatetimeMath datetimeMath;
public OrdinalDayOfWeekCalculator(DatetimeMath m) {
datetimeMath = m;
}
public Object getDate(int year, int month, int dayOfWeek, int ordinal) {
Object datetime = datetimeMath.createDatetime(year, month, 1);
if (datetimeMath.getDayOfWeek(datetime) == dayOfWeek) {
return datetime;
}
int xDayCount = 0;
while (xDayCount != ordinal) {
datetimeMath.increment(datetime);
if (datetimeMath.getDayOfWeek(datetime) == dayOfWeek) {
xDayCount++;
}
}
return datetime;
}
}
dans mon application Android, j'appellerais quelque chose comme
OrdinalDayOfWeekCalculator odowc =
new OrdinalDayOfWeekCalculator(new TimeMath());
Time canadianThanksgiving = (Time)odowc.getDate(
year, Calendar.OCTOBER, Time.MONDAY, 2);
si je veux réutiliser le même algorithme pour java.util.Calendar
, je voudrais juste écrire un calendrier de classe qui met en œuvre les trois méthodes dans DatetimeMath et puis utiliser
OrdinalDayOfWeekCalculator odowc2 =
new OrdinalDayOfWeekCalculator(new CalendarMath());
Calendar canadianThanksgivingCal = (Calendar)odowc2.getDate(
year, Calendar.OCTOBER, Calendar.MONDAY, 2);
j'ai utilisé l'approche stratégique dans un moteur assez complexe dans une application qui est un bon exemple. Essentiellement le rôle du moteur était d'aller et d'abord trouver une liste de personnes qui avaient un widget, son deuxième rôle était de comprendre qui étaient les 10 meilleures personnes avec un widget basé sur un nombre inconnu de paramètres (choses comme la distance de prix précédente affaires ensemble, ammount sur le stock, options d'expédition etc etc etc..)
essentiellement ce que nous avons fait était nous avons cassé le le problème en deux stratégies la première étant la récupération de données, car nous savions que nous avions de multiples sources de nos widgets et nous avions besoin d'être en mesure d'obtenir les données et de les transformer en une structure commune.
nous avons alors également réalisé que nous avions plusieurs algorithmes certains étaient basés sur la pondération des paramètres, d'autres étaient très étranges et propitery et je ne pouvais pas leur rendre justice sans sortir des visios et des graphiques et bien vous avez l'image, nous avons eu beaucoup d'algorithmes pour choisir les meilleurs.
notre service lui-même était très chose il a essentiellement défini les entrées, les sorties et a fait une certaine normalisation des données, il a également utilisé un modèle de fournisseur pour brancher les fournisseurs de données spécifiques à l'application et des fournisseurs de algorithmes qui ont utilisé la stratégie. C'était une assez bonne efficacité du système.
nous avons eu quelques débats si nous utilisions une stratégie ou un modèle de modèle que nous n'avons jamais résolu.
il y a quelques semaines, j'ai ajouté une interface Java commune qui a été implémentée par l'un de nos objets domain. Cet objet de domaine a été chargé à partir de la base de données, et la représentation de la base de données était un schéma d'étoile avec environ 10+ branches. Une des conséquences d'avoir un tel objet de domaine de poids lourd est que nous avons dû faire d'autres objets de domaine qui représentaient le même schéma, bien que moins de poids lourd. J'ai donc fait en sorte que les autres objets légers implémentent la même interface. Dit autrement nous avions:
public interface CollectibleElephant {
long getId();
String getName();
long getTagId();
}
public class Elephant implements CollectibleElephant { ... }
public class BabyElephant implements CollectibleElephant { ... }
à l'origine, je voulais utiliser CollectibleElephant
pour trier Elephant
S. Assez rapidement, mes coéquipiers ont glommé sur CollectibleElephant
pour exécuter des contrôles de sécurité, les filtrer comme ils sont envoyés à l'interface graphique, etc.
nous avons dû créer une interface d'approvisionnement tiers pour une plate-forme d'entreprise avec une base de données très compliquée. La soumission des données à fournir était une liste de nos types de données qui ont été placés dans une file d'attente prioritaire dans notre application afin qu'ils puissent être écrits à la base de données dans le bon ordre en raison de dépendances.
le processus pour écrire que les données étaient alors assez simple, continuer à enlever le haut de la file d'attente de priorité et ensuite choisir une stratégie basé sur le type d'objet que vous extrayez.
public class StrategyDemo {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
Item item1 = new Item("1234", 10);
Item item2 = new Item("5678", 40);
cart.addItem(item1);
cart.addItem(item2);
// pay by paypal
cart.pay(new PaypalStrategy("myemail@example.com", "mypwd"));
// pay by credit card
cart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"));
}
}
interface PaymentStrategy {
public void pay(int amount);
}
class CreditCardStrategy implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvv;
private String dateOfExpiry;
public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate) {
this.name = nm;
this.cardNumber = ccNum;
this.cvv = cvv;
this.dateOfExpiry = expiryDate;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid with credit/debit card");
}
}
class PaypalStrategy implements PaymentStrategy {
private String emailId;
private String password;
public PaypalStrategy(String email, String pwd) {
this.emailId = email;
this.password = pwd;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid using Paypal.");
}
}
class Item {
private String upcCode;
private int price;
public Item(String upc, int cost) {
this.upcCode = upc;
this.price = cost;
}
public String getUpcCode() {
return upcCode;
}
public int getPrice() {
return price;
}
}
class ShoppingCart {
// List of items
List<Item> items;
public ShoppingCart() {
this.items = new ArrayList<Item>();
}
public void addItem(Item item) {
this.items.add(item);
}
public void removeItem(Item item) {
this.items.remove(item);
}
public int calculateTotal() {
int sum = 0;
for (Item item : items) {
sum += item.getPrice();
}
return sum;
}
public void pay(PaymentStrategy paymentMethod) {
int amount = calculateTotal();
paymentMethod.pay(amount);
}
}
de wikipedia
dans la programmation informatique, le pattern de stratégie (également connu sous le nom de pattern de politique) est un pattern de conception de logiciel comportemental qui permet de sélectionner un algorithme à l'exécution. Au lieu d'implémenter un seul algorithme directement, le code reçoit des instructions d'exécution quant à ce qu'il faut utiliser dans une famille d'algorithmes
dans L'application de peinture de fenêtres, vous pouvez voir un modèle de stratégie où vous pouvez choisir la forme et la couleur indépendamment dans des sections différentes. Ici la forme et la couleur sont les algorithmes qui peuvent changer à l'exécution.
si vous voulez dessiner un cercle avec la couleur Rouge, plutôt que de fournir une option de "cercle rouge" ils vous laissent choisir le cercle et une couleur de votre choix.
Shape redCircle = new RedCircle(); // Without stretegy Pattern
Shaped redCircle = new Shape("red","circle"); // With Strategy pattern
sans motif de stratégie augmentera le nombre de classes avec le produit cartésien de forme et de couleur. Aussi l'interface change pour chaque application.