

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Des solutions
<a name="java-flow-making-changes-solutions"></a>

Vous pouvez utiliser les solutions suivantes pour éviter les modifications irréversibles. Pour plus d'informations, consultez [Modifications du code décideur](java-flow-making-changes-decider-code.md) et [Exemple de scénario](java-flow-making-changes-example-scenario.md).

## Utilisation de la gestion des versions
<a name="use-versioning"></a>

Dans cette solution, vous copiez le décideur dans une nouvelle classe, vous le modifiez, puis vous l'enregistrez sous une nouvelle version de flux de travail.

`VersionedDecider.java`

```
package sample.v2;
 
import com.amazonaws.services.simpleworkflow.flow.DecisionContext;
import com.amazonaws.services.simpleworkflow.flow.DecisionContextProviderImpl;
import com.amazonaws.services.simpleworkflow.flow.WorkflowClock;
import com.amazonaws.services.simpleworkflow.flow.annotations.Execute;
import com.amazonaws.services.simpleworkflow.flow.annotations.Workflow;
import com.amazonaws.services.simpleworkflow.flow.annotations.WorkflowRegistrationOptions;
 
import sample.Input;
 
@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 60, defaultTaskStartToCloseTimeoutSeconds = 5)
public interface Foo {
 
    @Execute(version = "2")
    public void sample(Input input);
 
    public static class Impl implements Foo {
 
        private DecisionContext decisionContext = new DecisionContextProviderImpl().getDecisionContext();
        private WorkflowClock clock = decisionContext.getWorkflowClock();
 
        @Override
        public void sample(Input input) {
            System.out.println("Decision (V2) WorkflowId: " + decisionContext.getWorkflowContext().getWorkflowExecution().getWorkflowId());
            clock.createTimer(5);
        }
 
    }
 
}
```

Dans le code Java mis à jour, le deuxième exécuteur de décision exécute les deux versions du flux de travail, permettant de poursuivre les exécutions à la volée indépendamment des modifications apportées à la version `2`.

`RunVersionedDecider.java`

```
package sample;
 
import com.amazonaws.services.simpleworkflow.flow.WorkflowWorker;
 
public class VersionedChange extends SampleBase {
 
    public static void main(String[] args) throws Exception {
        new VersionedChange().run();
    }
 
    public void run() throws Exception {
        // Start the first version of the decider, with workflow version 1
        WorkflowWorker before = new WorkflowWorker(service, domain, taskList);
        before.addWorkflowImplementationType(sample.v1.Foo.Impl.class);
        before.start();
 
        // Start a few executions with version 1
        startFiveExecutions("Foo.sample", "1", new Input());
 
        // Stop the first decider worker and wait a few seconds 
        // for its pending pollers to match and return
        before.suspendPolling();
        sleep(2000);
 
        // At this point, three executions are still open, with more decisions to make
 
        // Start a worker with both the previous version of the decider (workflow version 1) 
        // and the modified code (workflow version 2)
        WorkflowWorker after = new WorkflowWorker(service, domain, taskList);
        after.addWorkflowImplementationType(sample.v1.Foo.Impl.class);
        after.addWorkflowImplementationType(sample.v2.Foo.Impl.class);
        after.start();
 
        // Start a few more executions with version 2
        startFiveExecutions("Foo.sample", "2", new Input());
 
        printExecutionResults();
    }
 
}
```

Lorsque vous lancez le programme, toutes les exécutions se terminent avec succès.

## Utilisation des indicateurs de fonction
<a name="use-feature-flags"></a>

L'autre solution pour éviter les modifications irréversibles est de créer des branches de code qui prennent en charge deux implémentations de la même classe basées sur des données d'entrée au lieu des versions de flux de travail.

Lorsque vous choisissez cette approche, vous ajoutez des champs à vos objets d'entrée (ou en modifiez des champs existants) chaque fois que vous apportez de petites modifications. Pour les exécutions qui démarrent avant la migration, l'objet d'entrée ne disposera pas du champ (ou possédera une valeur différente). Ainsi, vous n'avez pas à augmenter le numéro de version.

**Note**  
Si vous ajoutez de nouveaux champs, veillez à ce que le processus de désérialisation JSON soit irréversible. Les objets sérialisés avant la présentation du champ doivent toujours être désérialisés avec succès après la migration. Étant donné que JSON définit une valeur `null` dès qu'un champ est manquant, utilisez toujours des types enveloppes (`Boolean` au lieu de `boolean`) et occupez-vous des cas dans lesquels la valeur est `null`.

`FeatureFlagDecider.java`

```
package sample.v1.featureflag;
 
import com.amazonaws.services.simpleworkflow.flow.DecisionContext;
import com.amazonaws.services.simpleworkflow.flow.DecisionContextProviderImpl;
import com.amazonaws.services.simpleworkflow.flow.WorkflowClock;
import com.amazonaws.services.simpleworkflow.flow.annotations.Execute;
import com.amazonaws.services.simpleworkflow.flow.annotations.Workflow;
import com.amazonaws.services.simpleworkflow.flow.annotations.WorkflowRegistrationOptions;
 
import sample.Input;
 
@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 60, defaultTaskStartToCloseTimeoutSeconds = 5)
public interface Foo {
 
    @Execute(version = "1")
    public void sample(Input input);
 
    public static class Impl implements Foo {
 
        private DecisionContext decisionContext = new DecisionContextProviderImpl().getDecisionContext();
        private WorkflowClock clock = decisionContext.getWorkflowClock();
 
        @Override
        public void sample(Input input) {
            System.out.println("Decision (V1 feature flag) WorkflowId: " + decisionContext.getWorkflowContext().getWorkflowExecution().getWorkflowId());
            clock.createTimer(5);
            if (!input.getSkipSecondTimer()) {
                clock.createTimer(5);
            }
        }
 
    }
}
```

Dans le code Java mis à jour, le code des deux versions du flux de travail est toujours enregistré pour la version `1`. Pourtant, après la migration, de nouvelles exécutions démarrent avec le champ `skipSecondTimer` des données d'entrée définies sur `true`.

`RunFeatureFlagDecider.java`

```
package sample;
 
import com.amazonaws.services.simpleworkflow.flow.WorkflowWorker;
 
public class FeatureFlagChange extends SampleBase {
 
    public static void main(String[] args) throws Exception {
        new FeatureFlagChange().run();
    }
 
    public void run() throws Exception {
        // Start the first version of the decider
        WorkflowWorker before = new WorkflowWorker(service, domain, taskList);
        before.addWorkflowImplementationType(sample.v1.Foo.Impl.class);
        before.start();
 
        // Start a few executions
        startFiveExecutions("Foo.sample", "1", new Input());
 
        // Stop the first decider worker and wait a few seconds 
        // for its pending pollers to match and return
        before.suspendPolling();
        sleep(2000);
 
        // At this point, three executions are still open, with more decisions to make
 
        // Start a new version of the decider that introduces a change 
        // while preserving backwards compatibility based on input fields
        WorkflowWorker after = new WorkflowWorker(service, domain, taskList);
        after.addWorkflowImplementationType(sample.v1.featureflag.Foo.Impl.class);
        after.start();
 
        // Start a few more executions and enable the new feature through the input data
        startFiveExecutions("Foo.sample", "1", new Input().setSkipSecondTimer(true));
 
        printExecutionResults();
    }
 
}
```

Lorsque vous lancez le programme, toutes les exécutions se terminent avec succès.