Question

imaginez que vous avez une fonction qui crée / copier / déplacer des fichiers. [Logique]

Pour le cas où un fichier qui doit être copié / créé existe déjà, vous souhaitez demander à l'utilisateur de remplacer le fichier ou non. [(G) UI]

Quelle est votre approche pour mettre en œuvre ce si (G) l'interface utilisateur et la logique sont complètement séparés?

La première chose qui me vient à l'esprit serait le modèle MVC, mais cela signifie que je dois l'utiliser partout où je besoin d'une interaction utilisateur.

Toutes les autres suggestions?

BTW: Comment voulez-vous implémenter dans les non-OO-langues

?
Était-ce utile?

La solution

Je vois deux façons:

  • Vous avez deux fonctions, file_exists(...) et copy_file(...). Le côté de l'interface utilisateur appelle toujours file_exists d'abord et demande à l'utilisateur si vous souhaitez copier le fichier est qu'il existe déjà.
  • Vous avez une seule fonction copy_file(bool force, ...), que par défaut échoue si le fichier existe. Donc, côté interface utilisateur appelle la version par défaut de la fonction, vérifiez si elle a échoué et pourquoi, si elle a été parce que le fichier existe déjà, demander à l'utilisateur et essayez à nouveau avec force=true.

Autres conseils

Si l'interface graphique et logique sont vraiment séparés, cette question ne devrait jamais se produire. Le programme devrait, par sa conception, soit remplacer ou n'écrasent pas basée sur une option qui a une valeur par défaut. Si l'interface graphique est disponible, l'option peut être réglée.

En fait, bien que l'approche évidente est d'avoir juste à et commencer la copie, vous pouvez faire un premier passage à la recherche de conflits, et vérifier que le dispositif cible a suffisamment de stockage gratuit. Ensuite, s'il y a un problème, mettre fin en ne faisant rien, à moins d'une interface graphique dans ce cas, vous pouvez signaler le problème et demander si quand même continuer.

Si vous voulez avoir une conception dans laquelle l'interface peut être invoquée sur un fichier par fichier, puis de concevoir la logique autour de ce comme un ensemble de n processus dont chacun des copies d'un fichier, et dispose d'une interface graphique disponible en option dans la section de rapports d'erreurs. L'interface graphique peut alors en relançant la logique de copie d'un fichier.

Dans une langue non OO Je mettre en œuvre une sorte de file d'attente d'événement où le parent (ou un enfant, selon votre conception) l'interface utilisateur pour les événements en sondé un drapeau « occupé » était vrai. Un tel événement permet de l'autre côté d'autres travaux en attendant un drapeau « ils ont répondu » à venir vrai. Bien sûr, un certain délai d'attente dans les deux sens devrait être observé ainsi que l'exclusion mutuelle. En fait, impliquer les principes de non-blocage d'E / S ou votre théorie préférée sur la programmation libre de verrouillage pratique ici.

Il y a des degrés de séparation .. processus peuvent communiquer. En fonction de langue de votre choix, vous avez des segments de mémoire partagée, sémaphores .. ou IPC via DB relationnelle avec des signaux primitifs. Il est difficile d'être plus précis avec une telle question générique.

Voir mon commentaire, un peu plus d'informations est nécessaire pour une réponse peut être conçu qui fonctionne au sein de votre langue de leur choix.

  

La première chose qui me vient à l'esprit serait le modèle MVC, mais cela signifie que je dois l'utiliser partout où je besoin d'une intervention de l'utilisateur.

Et c'est une mauvaise chose pourquoi? La séparation et la logique GUI est exactement ce que le modèle MVC est pour. Ne pas avoir peur de lui juste parce qu'il a un nom long a - dès que vous avez séparé GUI et de la logique que vous avez une « vue » et un « contrôleur », au moins, sinon un « modèle » - et si votre application a l'état, vous avez un modèle aussi. Vous venez peut ne pas avoir admis encore à vous.

D'après ce que je peux voir, il y a vraiment deux problèmes:

  1. Nous avons un algorithme (logique) dans laquelle nous aimerions reporter certaines opérations et décisions à autre chose (par exemple l'utilisateur via l'interface utilisateur).
  2. Nous voudrions éviter un couplage étroit entre l'algorithme et autre chose.

Si nous utilisons les langages OO, il y a plusieurs bagouts de conception qui traitent ces deux problèmes spécifiques.

  • modèle de la méthode de modèle peut résoudre # 1. Il ne résout pas # 2 très bien parce que la mise en œuvre typique est par inheritence.
  • modèle d'observateur semble trop prometteur.

Alors, vraiment, il est le choix et le mélange le plus simple pour les besoins et le mieux adapté à la langue.

En pratique, si parler de C # par exemple, nous pouvons mettre en œuvre hybride Méthode modèle et d'observation comme ceci:

// This will handle extensions to the FileCopy algorithm
abstract class FileCopyExtention
{
 public abstract Response WhatToDoWhenFileExists();
}


// the copy function, pure logic
public static void Copy(string source, string destination, FileCopyExtention extension) 
{
 if (File.Exists(destination))
 {
  var response = _extension.WhatToDoWhenFileExists();
  if (response == overwrite)
   // overwrite the file
  else
   // error
 }
}

// This is our user-interactive UI extension
class FileCopyUI : FileCopyExtention
{
 public override Response WhatToDoWhenFileExists()
 {
  // show some UI, return user's response to the caller
 }
}

// the program itself
void Main()
{
 Copy("/tmp/foo", "/tmp/bar", new FileCopyUI());
}

En variante du thème, vous pouvez utiliser des événements, des délégués ou quelle que soit la langue de votre choix fournit.

En C, cela pourrait être un pointeur de fonction, en C ++ une référence à une classe, je suppose.

Qu'en est-il cette approche [pseudo-code]:

UIClass
{
    //
    // Some code
    //

    bool fileCopied = false;

    do {
        try {
            fileCopied = CopyFile(fileName);
        } catch (FileExists) {
            //
            // Ask "File exists! Overwrite?" If "No", exit do-loop
            //
        } catch (FileLocked) {
            //
            // Ask "File Locked! Repeat?",   If "No", exit do-loop
           //
        } catch (etc...) {
            //
            // etc.
            //    
        }
    } while (!fileCopied);

    //
    // Some code
    //
}

LogicClass
{
    //
    // Some code
    //

    bool CopyFile(string fileName)
    {
        //
        // copy file
        //
    }

    //
    // Some code
    //

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top