2010-10-12 4 views
0

J'ai développé cette classe pour charger des plugins sous la forme d'objets partagés pour une application. J'ai actuellement pensé à 2 façons de charger les noms de fichiers de tous les plugins à charger par l'application. J'ai écrit une interface pour charger les noms de fichiers. J'ai quelques questions sur la façon d'améliorer cette conception. S'il vous plaît aider. Merci.Problème de conception avec le chargeur d'objet partagé

EDIT: modification de code par retour: D.

#include "Plugin.h" 

//This class is an interface for loading the list of file names of shared objects. 
//Could be by loading all filienames in a dir, or by loading filenames specified in a file. 
class FileNameLoader 
{ 
    public: 
     virtual std::list<std::string>& LoadFileNames() = 0; 
}; 

class PluginLoader 
{ 
public: 
    explicit PluginLoader(LoadingMethod, const std::string& = ""); 
    virtual ~PluginLoader(); 

    virtual bool Load(); 

    virtual bool LoadPlugins(FileNameLoader&); 
    virtual bool LoadFunctions(); 

protected: 
private: 
    explicit PluginLoader(const PluginLoader&); 
    PluginLoader& operator=(const PluginLoader&); 

    bool LoadSharedObjects(); 

    list<std::string> l_FileNames; 
    list<PluginFunction*> l_Functions; 
    list<Plugin*> l_Plugins; 
}; 

Tout ce qui semble moche encore? Merci pour les commentaires quand même.

+0

Sonne comme il pourrait être temps d'appliquer [YAGNI] (http://en.wikipedia.org/wiki/You_ain't_gonna_need_it) :) – sje397

+0

en plus au-dessus, vous pouvez mettre en cache vos données de plug-ins comme 'std :: unordered_map > ' – erjot

Répondre

0

Vous avez créé une interface de qualité, mais vous ne l'utilisez pas. Et vous stockez ensuite les noms de fichiers dans un membre privé l_FileNames.

Je voudrais modifier le constructeur PluginLoader pour accepter une référence FileNameLoader et utiliser cette référence pour charger les noms de fichiers. De cette façon, vous n'aurez pas besoin de LoadingMethod dans la classe PluginLoader.

Ecrivez deux classes implémentant l'interface FileNameLoader, une pour chaque méthode de chargement.

modifier:

class FileNameLoader 
{ 
    public: 
     //RVO will work right? :D 
     virtual std::list<std::string>& LoadFileNames() = 0; 
}; 

class FileNameLoaderByFile : public FileNameLoader 
{ 
public: 
    std::list<std::string>& LoadFileNames() 
    { 
     // ... 
    } 

} 

class FileNameLoaderByDirectory : public FileNameLoader 
{ 
public: 
    std::list<std::string>& LoadFileNames() 
    { 
     // ... 
    } 

} 



class PluginLoader 
{ 
public: 
    explicit PluginLoader(FileNameLoader& loader) 
    { 
    fileNames = loader.LoadFileNames() 
    } 

    virtual ~PluginLoader(); 

private: 
    list<std::string> fileNames; 
}; 
+0

Je suis assez clair sur le fait que peu importe de quelle façon je génère les noms de fichiers, ils seront tous une liste. C'est pourquoi j'ai écrit une interface pour juste la fonctionnalité de génération de nom de fichier. – nakiya

+0

Oui, c'est pourquoi je vous ai dit que vous n'avez pas besoin de la méthode de chargement dans votre classe, vous avez déjà l'interface. – vulkanino

+0

Et si je le change en: 'Virtual bool LoadPlugins (FileNameLoader *);'? Et fournir le chargeur de nom de fichier de l'extérieur? – nakiya

1

Il me semble que vous avez votre extension de la fonctionnalité à travers le enum, FileNameLoader et les PluginLoader classes. Ma suggestion serait de créer une classe PluginLoaderByFile, et une classe PluginLoaderByDir - possiblement avec l'une héritant d'une autre, ou possiblement avec une classe de base commune. De cette façon, vous pouvez définir d'autres sous-classes, y compris le code supplémentaire nécessaire, et le garder encapsulé, si nécessaire, en bas de la piste.

Ceci facilite également l'utilisation, par ex. les modèles factory ou builder à l'avenir.

+0

Ne serait pas beaucoup de code à dupliquer alors? Je suis désolé d'être implacable, je veux seulement connaître le raisonnement. : D – nakiya

+0

Pourquoi le code serait-il dupliqué? Cela vous permet de mettre du code commun dans la classe de base. – sje397

+0

Deux choses que je voudrais vraiment éviter: (1) perdre la sécurité de type avec par ex. un vecteur de paramètres, ou (2) une fonction qui renvoie toujours une liste de taille 1. – sje397

0

En ce qui concerne votre déclaration du problème actuel. U peut utiliser

  • vecteur pour params ou
  • puisque u utilisent une chaîne u peut aussi bien l'analyser en utilisant des délimiteurs (dire "", "")

Cependant, je ne laisserait pas les params ou la méthode de chargement être visibles dans le PluginLoader. Au lieu de cela, utiliserait une interface commune/générique au lieu de

Questions connexes