108 votes

Exemple concret du modèle de stratégie

J'ai lu des articles sur le Principe de l'OCP et comment utiliser le modèle de stratégie pour y parvenir.

J'allais essayer d'expliquer cela à quelques personnes, mais le seul exemple auquel je peux penser est l'utilisation de différentes classes de validation en fonction du statut d'une "commande".

J'ai lu quelques articles en ligne, mais ils ne décrivent généralement pas une véritable raison d'utiliser la stratégie, comme la génération de rapports/factures/validation, etc...

Y a-t-il des exemples concrets où vous pensez qu'un modèle de stratégie est courant ?

3voto

grootjans Points 257

Êtes-vous sûr que le statut d'une "commande" n'est pas un modèle d'état ? J'ai l'intuition qu'une commande ne sera pas traitée différemment en fonction de son état.

Prenons par exemple la méthode Navire sur l'ordre :

order.Ship();
  • Si le mode d'expédition varie en en fonction de son statut, alors vous avez un modèle de stratégie.
  • Si toutefois le site Navire() La méthode ne réussit que lorsque la commande a été payée, et la commande n'a pas encore été expédiée, vous avez un modèle d'état.

Le meilleur exemple du modèle d'état (et d'autres modèles) que j'ai trouvé se trouve dans le livre " Les premiers modèles de conception (Head First Design Patterns) ", ce qui est étonnant. Une deuxième place proche sera La série de modèles de blogs de David Cumps .

2voto

JoshBerke Points 34238

J'ai utilisé l'approche stratégique dans un moteur assez complexe dans une application qui en est un bon exemple. Essentiellement, le rôle du moteur était d'aller chercher une liste de personnes qui avaient un widget, son second rôle était de déterminer quelles étaient les 10 meilleures personnes avec un widget en se basant sur un nombre inconnu de paramètres (des choses comme la distance entre les prix et les affaires précédentes, la quantité en stock, les options de livraison etc etc...).

Nous avons essentiellement décomposé le problème en deux stratégies, la première étant la récupération des données, car nous savions que nos widgets provenaient de plusieurs sources et que nous devions être en mesure de récupérer les données et de les transformer en une structure commune.

Nous avons également réalisé que nous avions de multiples algorithmes, certains basés sur la pondération des paramètres, d'autres très bizarres et bizarres et que je ne pouvais pas leur rendre justice sans sortir des visions et des graphiques, et vous voyez le tableau, nous avions beaucoup d'algorithmes pour sélectionner les meilleures personnes.

Notre service lui-même était très simple : il définissait essentiellement les entrées, les sorties et effectuait une certaine normalisation des données. Il utilisait également un modèle de fournisseur pour intégrer les fournisseurs de données et d'algorithmes spécifiques à l'application qui utilisaient la stratégie. C'était un système assez efficace.

Nous avons eu quelques débats pour savoir si nous utilisions une stratégie ou un modèle, mais nous ne les avons jamais résolus.

2voto

anomal Points 758

Disons que vous voulez écrire un algorithme pour calculer le nième Xjour d'un mois et d'une année donnés, par exemple, le deuxième lundi d'octobre 2014. Vous souhaitez utiliser la classe Time 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);
}

Dans 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 souhaite réutiliser le même algorithme pour java.util.Calendar je me contenterais d'écrire une classe CalendarMath qui implémente les trois méthodes de DatetimeMath, puis j'utiliserais la méthode

OrdinalDayOfWeekCalculator odowc2 = 
        new OrdinalDayOfWeekCalculator(new CalendarMath());
Calendar canadianThanksgivingCal = (Calendar)odowc2.getDate(
        year, Calendar.OCTOBER, Calendar.MONDAY, 2);

1voto

Alan Points 4249

Il y a quelques semaines, j'ai ajouté une interface Java commune qui était mise en œuvre par l'un de nos objets de domaine. Cet objet de domaine était chargé à partir de la base de données, et la représentation de la base de données était un schéma en étoile avec plus de 10 branches. L'une des conséquences d'avoir un objet de domaine aussi lourd est que nous avons dû créer d'autres objets de domaine qui représentaient le même schéma, bien que moins lourds. J'ai donc fait en sorte que les autres objets légers implémentent la même interface. Mis 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 de trier Elephant s. Assez rapidement, mes coéquipiers ont glommed sur CollectibleElephant pour effectuer des contrôles de sécurité, les filtrer lorsqu'ils sont envoyés à l'interface graphique, etc.

1voto

Coxy Points 5256

Nous avons dû créer une interface de provisionnement tiers pour une plate-forme d'entreprise dotée d'une base de données très complexe. La soumission des données à provisionner se faisait sous la forme d'une liste de nos types de données qui étaient placés dans une file d'attente prioritaire dans notre application afin qu'ils puissent être écrits dans la base de données dans le bon ordre en raison des dépendances.

Le processus d'écriture de ces données était alors assez simple, il fallait continuer à les faire apparaître en haut de la liste des priorités, puis choisir une stratégie en fonction du type d'objet extrait.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X