0
votes

Y a-t-il un modèle de conception pour une entrée transmise à N méthodes qui renvoient chacune l'entrée de la méthode suivante

J'aimerais savoir s'il y a un modèle de conception pour ce problème: strong>

Une entrée est utilisée pour construire un objet (via constructeur ou via la méthode, je m'en fiche) , cet objet est alimenté sur la méthode ou le constructeur suivant. Ceci est répété sur un ensemble de processeurs spécifié par l'utilisateur, jetant évidemment des exceptions s'il y a une pause dans la chaîne des entrées requises pour les processeurs. P>

La sortie de tous, certains ou aucun des processeurs mis en œuvre est le même objet. P>

J'ai environ 6 processeurs planifiés, éventuellement plus à l'avenir. P>

Composition: strong> Je ne sais pas que j'aime le modèle de conception de la composition, car tous les objets ne sont pas destinés à être une sortie de ce processus et je ne peux pas penser à ne pas générer des valeurs nulles sans que l'utilisateur sache que cela ne soit pas nul. P>

Chaîne de responsabilité: strong> La chaîne de responsabilité est la voie à suivre selon ce que j'ai entendu mais je ne suis pas sûr de le comprendre. Ce modèle de conception suggère-t-il de passer n Pointeurs de fonction à une fonction qui traverse chacune? Si tel est le cas, je ne sais pas comment configurer la fonction qui est passée n-points de fonction. p>

ma tentative: strong> p>

J'ai deux interfaces héritées par n classes, c'est-à-dire (premier-cuillère, firstInput, fianctoutput, seconde-déprocesseur, secondoDeCess .., NProcesseur, Noutput) P>

    IChainedProcessor previous = FirstProcessor(originalInput)

    foreach(IChainedProcessor processor in processorList.Skip(1)
    {
        IChainedOutput current = processor.Run(previous)

        previous = current;       
    }

    FinalOutputObj output = previous.GetFinalOutput();


8 commentaires

Cela ressemble à un pipeline Dataflow


Quel est le but de mettre ces processeurs dans une liste? Normalement, si vous devez exécuter plusieurs méthodes, codez simplement chaque étape une après l'autre, par exemple. comme des lignes séparées dans un fichier .CS, pas comme des éléments dans une liste.


Cela ressemble à une chaîne de responsabilité si je suppose que vous pourriez utiliser un observateur aussi en fonction du flux.


@Johnwu Si vous regardez ma description, vous constaterez que je mentionne que la liste est spécifiée par l'utilisateur. Si l'utilisateur veut une solution rapide plus rapide, elle pourrait sélectionner les premiers processeurs. Il existe au moins deux processeurs qui fournissent une sortie fantaisie que chaque cas d'utilisation ne voudra ou pas besoin.


Comme déjà mentionné par @thegeneral - avez-vous eu une partie à Dataflow Pipeline ?


Pour moi, ça sonne comme Interface fluide Plus que tout ...


L'ordre des processeurs peut-il être complètement aléatoire? Ou est-ce que si vous avez des processeurs 123456, vous ne pouvez que omettre les processeurs de sorte qu'il devienne 12-4-6 signifie que l'ordre général reste le même? En d'autres termes, une chaîne 6-25-4 n'est pas possible?


@ReaSurria Non, ils ne peuvent pas être complètement aléatoires. 6-25-4 serait impossible. La sortie doit être identique à celle d'une entrée de processeurs. Actuellement, c'est un à un (une sortie de processeur correspond à une entrée de processeur) mais si la solution est simple, alors dans certains de mes cas, il serait logique d'avoir la sortie d'un processeur être l'entrée pour plusieurs autres processeurs.


3 Réponses :


0
votes

Si j'ai bien compris votre explication correctement, vous pouvez utiliser des délégués pour surmonter votre problème. L'un des points importants sur les délégués est qu'elles peuvent être chaînées ensemble afin que vous puissiez appeler n'importe quel nombre de méthodes dans un seul événement.


1 commentaires

Ce n'est pas très utile. Oui, vous pouvez les chaîner, mais comment suggérez-vous de faire face aux intrants changeants et aux sorties variables.



-1
votes

Chaque processeur transformant une entrée spécifique en une sortie spécifique. Par conséquent, la mise en œuvre du processeur ne devrait connaître que deux types.

public interface IDataInput { }
public interface IDataStep1 { }
public interface IDataStep2 { }
public interface IDataStep3 { }
public interface IDataStepN { }
public interface IDataOutput { }

public interface IStepProcessor<TInput, TOutput>
{
    TOutput Process(TInput input);
}

public delegate TOutput Conveyor<TInput, TOutput>(TInput input);

public class Factory
{
    private readonly IStepProcessor<IDataInput, IDataStep1> m_Step1;
    private readonly IStepProcessor<IDataStep1, IDataStep2> m_Task2;
    private readonly IStepProcessor<IDataStep2, IDataStep3> m_Task3;
    private readonly IStepProcessor<IDataStep3, IDataStepN> m_TaskN;
    private readonly IStepProcessor<IDataStepN, IDataOutput> m_FinalTask;

    public Factory(
        IStepProcessor<IDataInput, IDataStep1> task1,
        IStepProcessor<IDataStep1, IDataStep2> task2,
        IStepProcessor<IDataStep2, IDataStep3> task3,
        IStepProcessor<IDataStep3, IDataStepN> taskN,
        IStepProcessor<IDataStepN, IDataOutput> finalTask
        )
    {
        m_Step1 = task1;
        m_Task2 = task2;
        m_Task3 = task3;
        m_TaskN = taskN;
        m_FinalTask = finalTask;
    }
    public Conveyor<IDataInput, IDataOutput> BuildConveyor()
    {
        return (input) =>
        {
            return m_FinalTask.Process(
                m_TaskN.Process(
                    m_Task3.Process(
                        m_Task2.Process(
                            m_Step1.Process(input)))));
        };
    }
}


public class Client
{
    private readonly Conveyor<IDataInput, IDataOutput> m_Conveyor;

    public Client(Conveyor<IDataInput, IDataOutput> conveyor)
    {
        m_Conveyor = conveyor;
    }

    public void DealWithInputAfterTransformingIt(IDataInput input)
    {
        var output = m_Conveyor(input);
        Console.Write($"Mind your business here {typeof(IDataOutput).IsAssignableFrom(output.GetType())}");
    }
}

public class Program {

    public void StartingPoint(IServiceProvider serviceProvider)
    {
        ISomeDIContainer container = CreateDI();
        container.Register<IStepProcessor<IDataInput, IDataStep1>, Step1Imp>();
        container.Register<IStepProcessor<IDataStep1, IDataStep2>, Step2Imp>();
        container.Register<IStepProcessor<IDataStep2, IDataStep3>, Step3Imp>();
        container.Register<IStepProcessor<IDataStep3, IDataStepN>, StepNImp>();
        container.Register<IStepProcessor<IDataStepN, IDataOutput>, StepOImp>();

        container.Register<Factory>();

        Factory factory = container.Resolve<Factory>();
        var conveyor = factory.BuildConveyor();
        var client = new Client(conveyor);
    }
}


1 commentaires

Il y a beaucoup de répétitions ici et ne traite pas du fait qu'il existe un nombre variable de tâches à faire. Je devrais créer de nombreuses étapes et permettre des étapes non assurées. J'aurais également besoin d'une instanciation différente pour chaque combinaison de tâches. Très verbeux. Peut-être que je ne peux pas échapper à la verbosité.



1
votes

Vous pouvez essayer une approche de décorateur comme ceci: xxx

L'utilisation serait quelque chose comme ci-dessous: xxx

la sortie de la sortie de Cet exemple est: xxx

La classe de processeur abstrait fournit une méthode de modèle que vous pouvez implémenter dans des sous-classes. Donc, chaque classe ProcessorX définit uniquement myLogic (ichainOutput d'entrée)

Les processeurs s'étendent pour appliquer la préservation du temps de compilation de l'ordre du processeur. Il est donc impossible de construire une chaîne où le processor vient avant le processora. Il est possible de construire une chaîne qui omet des processeurs comme dans l'exemple ci-dessus.

L'exemple que je fournis ici ne répond pas à la production finale, ce que je sais est l'une de vos principales préoccupations. Pour faire face à la question, je préférerais construire une classe de mappage pour convertir ichainOutput au format final (je ne connais pas la structure réelle de vos données, alors cela n'est peut-être pas possible).

Dans certains de mes cas, il serait logique d'avoir la sortie d'un processeur être l'entrée pour plusieurs autres processeurs

Utilisation de ce modèle Il serait également possible de construire un «arbre» ​​du processeur plutôt qu'une chaîne, en permettant à la classe du processeur d'avoir une liste des prochaines étapes. Votre usage deviendrait alors quelque chose comme ceci: xxx

J'espère que cela peut vous aider.


0 commentaires