Je suis en train de refactoriser un tas de vieux codes. Mon objectif principal est de découpler le comportement de la base de données. L'implémentation actuelle accède directement à la base de données, ce qui rend difficile le test et la mise en œuvre de couches de cache, etc ... Jusqu'à présent, j'utilise une combinaison d'inversion de dépendance et de lecteurs/graveurs avec beaucoup de succès. atteint certains de nos types les plus complexes.Lecteurs/écrivains et persistance découplée des classes dérivées
J'ai une classe d'utilisateur de base abstraite qui encapsule des informations communes à tous nos types d'utilisateurs. Hériter de la classe de base est un certain nombre de spécialisations du type d'utilisateur de base, dont chacune encapsule des informations spécifiques à ce type.
Si j'ai un pointeur ou une référence à la classe de base et que j'ai besoin de maintenir cet utilisateur dans la base de données, comment savoir quel script utiliser? Si je devais utiliser l'écrivain pour la classe de base, les informations spécifiques aux classes dérivées seraient perdues. Mettre une méthode abstraite getUserType() sur la classe de base qui doit ensuite être implémentée par chaque dérivée semble être un peu un hack. Cela pourrait être un cas de double expédition, mais les détails de mise en œuvre sont un peu flou pour moi.
class User
{
public:
std::string
name() const
{
return m_name;
}
void
name(const std::string& name)
{
m_name = name;
}
private:
std::string m_name;
}
class EmailUser : User
{
public:
std::list<std::string>
emails() const
{
return m_emails;
}
void
emails(const std::string<std::string>& emails)
{
m_emails = emails;
}
private:
std::set<std::string> m_emails;
}
class UserWriter
{
public:
virtual void
write(User& user) = 0;
}
class DBUserWriter : UserWriter
{
public:
void
write(User& user)
{
SQLExecute("SOME SQL UPDATE STMT %s", user.name());
}
}
class DBEmailUserWriter : UserWriter
{
public:
void
write(User& user)
{
m_baseUserWriter.write(user);
SQLExecute("SOME SQL UPDATE STMT %s", user.email.front());
}
private:
DBUserWriter m_baseUserWriter;
}
Ainsi, le seul inconvénient que je peux voir avec votre solution est qu'il me demande d'utiliser le même auteur pour tous les utilisateurs type rendant difficile de mélanger et de faire correspondre les mécanismes de mise en cache ou les magasins de données. – MrEvil
Vous pouvez avoir plusieurs écrivains. J'ai mis à jour le code, vérifiez si c'est ce que vous cherchez. –