Vue d'ensemble
Permettez-moi de vous suggérer quelques idées pour gérer les propriétés "lourds" comme blobs, les images, les fichiers. Rappelez-vous, il n'y a pas "une solution pour tous". Personnellement, je rejette l'idée d'un drapeau «charger toutes les propriétés lourdes», & suggérer des idées alternatives. Avant de poursuivre, je continue, s'il vous plaît, ignorez les petites erreurs de syntaxe ou de logique et concentrez-vous sur la logique des exemples de code.
[1] Définir Exemple
Tout d'abord, nous allons commencer par un exemple simple:
public class EmployeeClass
{
public:
int Key;
char FirstName[150];
char LastName[150];
Image* Photo; // <- picture
Blob* Contract; // <- scanned contract
}; // class
Tout d'abord, vous ne devez pas charger ou ne se charge pas, le "lourd" propriétés, parce que le modèle "Entité" ou une autre technique de programmation le dit.
En fait, je n'ajouterais pas de drapeau pour les objets lourds, car cela signifie charger toutes les propriétés "lourdes" ou ne charger aucune propriété "lourde". Et, parfois, vous devrez peut-être charger certains d'entre eux, mais pas tous.
[2] Propriétés de charge
Habituellement, la logique d'un programme, indique, au moment de charger les propriétés.
La pratique courante d'utiliser un son constructeur différent, pour chaque cas:
public class EmployeeClass
{
public:
int Key;
char FirstName[150];
char LastName[150];
Image* Photo;
Blob* Contract;
public:
// --> generic constructor
EmployeeClass()
{
Key = 0;
strcpy(FirstName, "");
strcpy(LastName, "");
Photo = null;
Contract = null;
} // EmployeeClass()
// --> "light" constructor
EmployeeClass
(
int AKey,
char* AFirstName,
char* ALastName
)
{
Key = AKey;
strcpy(FirstName, AFirstName;
strcpy(LastName, ALastName);
Photo = null;
Contract = null;
} // EmployeeClass()
// --> "heavy" constructor
EmployeeClass
(
int AKey,
char* AFirstName,
char* ALastName,
Image* APhoto,
Blob* AContract
)
{
Key = AKey;
strcpy(FirstName, AFirstName;
strcpy(LastName, ALastName);
Photo = APhoto;
Contract = AContract;
} // EmployeeClass()
void Insert();
}; // class
void Test()
{
...
int AKey = 0;
char AFirstName[150];
char ALastName[150];
Image* APhoto = null;
Blob* AContract = null;
// --> calling "light" constructor
AKey = 1;
strcpy(AFirstName, "Mary");
strcpy(ALastName, "Thompson");
EmployeeClass* AEmployee = new EmployeeClass
(AKey, AFirstName, ALastName);
AEmployee->Insert();
// --> calling "heavy" constructor
AKey = 2;
strcpy(AFirstName, "John");
strcpy(ALastName, "Doe");
Image* APhoto = LoadPhoto();
Blob* AContract = LoadContract();
EmployeeClass* AEmployee = new EmployeeClass
(AKey, AFirstName, ALastName, APhoto, AContract);
AEmployee->Insert();
// --> calling "dummy" constructor,
// --> more work, but, more flexible
AKey = 1;
strcpy(AFirstName, "Mary");
strcpy(ALastName, "Thompson");
EmployeeClass* AEmployee = new EmployeeClass();
AEmployee->Key = AKey;
strcpy(AEmployee->FirstName, AFirstName);
strcpy(AEmployee->LastName, ALastName);
AEmployee->Photo = LoadPhoto();
AEmployee->Contract = LoadContract();
AEmployee->Insert();
...
} // void Test()
De nombreux développeurs utilisent uniquement le « constructeur de lumière commun », & rejette l'idée d'avoir plusieurs constructeurs.
[3] Aide supplémentaire
Sautons, pour un moment, les propriétés "lourds", se poursuivra plus tard.
Ceci est une suggestion que de nombreux développeurs C/C++ n'aiment pas, mais, personnellement, je trouve très utile lorsqu'il s'agit d'objets d'entité. J'utilise "l'initialisation en deux étapes".
Pour chaque classe d'entité, je déclare un constructeur, sans paramètre qui efface les champs, et, ajoute, une méthode virtuelle, avec un identifiant très spécifique, qui prend le rôle de constructeur.
Ensuite, je peux ajouter plusieurs méthodes virtuelles qui fonctionnent comme des constructeurs, comme décider wheter charger les propriétés « lourds » ou non.
Ainsi, l'exemple précédent devient quelque chose comme ceci:
public class EmployeeClass
{
public:
bool F_EmployeeClass_IsReady;
public:
int Key;
char FirstName[150];
char LastName[150];
Image* Photo;
Blob* Contract;
public:
// --> only generic constructor
Employee()
{
F_EmployeeClass_IsReady = false;
Key = 0;
strcpy(FirstName, "");
strcpy(LastName, "");
Photo = null;
Contract = null;
} // EmployeeClass()
virtual bool IsReady()
{
return F_EmployeeClass_IsReady;
} // bool IsReady(...)
// --> works like "generic" constructor from previous example
virtual void Create()
{
Key = 0;
strcpy(FirstName, "");
strcpy(LastName, "");
Photo = null;
Contract = null;
F_EmployeeClass_IsReady = true;
} // void Create()
// --> works like "light" constructor from previous example
virtual void CreateLight
(
int AKey,
char* AFirstName,
char* ALastName
)
{
Key = AKey;
strcpy(FirstName, AFirstName);
strcpy(LastName, ALastName);
Photo = null;
Contract = null;
F_EmployeeClass_IsReady = true;
} // void CreateLight()
virtual void Destroy()
{
F_EmployeeClass_IsReady = false;
} // void Destroy()
// --> works like "heavy" constructor from previous example
virtual void CreateHeavy
(
int AKey,
char* AFirstName,
char* ALastName,
Image* APhoto,
Blob* AContract
)
{
Key = AKey;
strcpy(FirstName, AFirstName);
strcpy(LastName, ALastName);
Photo = APhoto;
Contract = AContract;
F_EmployeeClass_IsReady = true;
} // void CreateHeavy()
void Insert();
}; // class
void Test()
{
...
int AKey = 0;
char AFirstName[150];
char ALastName[150];
Image* APhoto = null;
Blob* AContract = null;
// --> calling "light" constructor
AKey = 1;
strcpy(AFirstName, "Mary");
strcpy(ALastName, "Thompson");
EmployeeClass* AEmployee = new EmployeeClass();
AEmployee->CreateLight(AKey, AFirstName, ALastName);
AEmployee->Insert();
AEmployee->Destroy();
delete AEmployee;
// --> calling "heavy" constructor
AKey = 2;
strcpy(AFirstName, "John");
strcpy(ALastName, "Doe");
Image* APhoto = LoadPhoto();
Blob* AContract = LoadContract();
EmployeeClass* AEmployee = new EmployeeClass();
AEmployee->CreateHeavy
(AKey, AFirstName, ALastName, APhoto, AContract);
AEmployee->Insert();
AEmployee->Destroy();
delete AEmployee;
// --> calling "dummy" constructor,
// --> more work, but, more flexible
AKey = 1;
strcpy(AFirstName, "Mary");
strcpy(ALastName, "Thompson");
EmployeeClass* AEmployee = new EmployeeClass();
AEmployee->Create();
AEmployee->Key = AKey;
strcpy(AEmployee->FirstName, AFirstName);
strcpy(AEmployee->LastName, ALastName);
AEmployee->Photo = LoadPhoto();
AEmployee->Contract = LoadContract();
AEmployee->Insert();
AEmployee->Destroy();
delete AEmployee;
...
} // void Test()
Dans l'exemple précédent, chaque entité est créée à l'aide de 2 étapes, le constructeur « factice », et une méthode complémentaire, différente pour chaque cas, avec un identifiant significatif, utile pour choisir comment préparer un objet entité.
Il en va de même pour la destruction de chaque objet.
[4] Méthodes Propriétés lourd
Enfin, vous voudrez peut-être ajouter un peu de méthode qui sont en charge de chargement des propriétés « lourdes » en cas de besoin. Parfois sont appelés explicitement, et parfois, appelés automatiquement.
public class EmployeeClass
{
public:
bool F_EmployeeClass_IsReady;
public:
int Key;
char FirstName[150];
char LastName[150];
Image* Photo;
Blob* Contract;
public:
// --> only generic constructor
Employee()
{
F_EmployeeClass_IsReady = false;
Key = 0;
strcpy(FirstName, "");
strcpy(LastName, "");
Photo = null;
Contract = null;
} // EmployeeClass()
virtual bool IsReady()
{
return F_EmployeeClass_IsReady;
} // bool IsReady(...)
void LoadPhoto();
void SavePhoto();
void LoadContract();
void SaveContract();
// --> works like "generic" constructor from previous example
virtual void Create()
{
Key = 0;
strcpy(FirstName, "");
strcpy(LastName, "");
Photo = null;
Contract = null;
F_EmployeeClass_IsReady = true;
} // void Create()
// --> works like "light" constructor from previous example
virtual void CreateLight
(
int AKey,
char* AFirstName,
char* ALastName
)
{
Key = AKey;
strcpy(FirstName, AFirstName);
strcpy(LastName, ALastName);
Photo = null;
Contract = null;
F_EmployeeClass_IsReady = true;
} // void CreateLight()
virtual void Destroy()
{
F_EmployeeClass_IsReady = false;
} // void Destroy()
// --> works like "heavy" constructor from previous example
virtual void CreateHeavy
(
int AKey,
char* AFirstName,
char* ALastName,
Image* APhoto,
Blob* AContract
)
{
Key = AKey;
strcpy(FirstName, AFirstName);
strcpy(LastName, ALastName);
Photo = APhoto;
Contract = AContract;
F_EmployeeClass_IsReady = true;
} // void CreateHeavy()
// --> works like "heavy" constructor from previous example
virtual void CreateAndLoad
(
int AKey,
char* AFirstName,
char* ALastName
)
{
Key = AKey;
strcpy(FirstName, AFirstName);
strcpy(LastName, ALastName);
LoadPhoto();
LoadContract;
F_EmployeeClass_IsReady = true;
} // void CreateAndLoad()
void Insert();
}; // class
void Test()
{
...
int AKey = 0;
char AFirstName[150];
char ALastName[150];
Image* APhoto = null;
Blob* AContract = null;
// --> calling "load" constructor
AKey = 1;
strcpy(AFirstName, "Mary");
strcpy(ALastName, "Thompson");
EmployeeClass* AEmployee = new EmployeeClass();
AEmployee->CreateLoad(AKey, AFirstName, ALastName);
AEmployee->Insert();
AEmployee->Destroy();
delete AEmployee;
...
} // void Test()
Avec les méthodes supplémentaires, vous pouvez avoir un constructeur [fake] qui les ignore, et ne pas charger les propriétés « lourds », un constructeur [fake] qui les appellent.Ou, utilisez le constructeur [faux] qui ne les utilise pas, & appelez explicitement le chargeur pour une propriété "lourde" spécifique.
Ceux-ci, aide aussi, si vous chargez des images à partir d'un chemin de système de fichiers, & les sauver dans un champs de base de données, ou vice-versa, charger des fichiers à partir d'un champ de base de données, & les sauver à un chemin de système de fichiers.
Cheers.
Merci pour l'explication détaillée. C'est très proche de ce que nous faisons actuellement, et cela fonctionne assez bien. Il n'est cependant pas sûr de la manière dont il gère le contenu lourd. –
@Kajetan Abt: Mon sugg. était destiné à ("penser différemment"), gérer les propriétés d'une manière alternative, savoir dès le début où il va exiger ces propriétés, et ne pas détecter après, si elles ont été chargées. Bonne chance. – umlcat