web-dev-qa-db-fra.com

Bonne conception de classe par exemple

J'essaie de trouver le meilleur moyen de concevoir une classe dont les propriétés sont conservées dans une base de données. Prenons un exemple de base de Person. Pour créer une nouvelle personne et la placer dans la base de données, je souhaite que la propriété DateOfBirth soit facultative (c'est-à-dire NULLable dans la base de données).

Voici mon exemple de code:

namespace BusinessLayer
{
    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DateOfBirth { get; set; }
    }
}

Je ne sais pas si les champs doivent être publics ou non. Devrais-je le faire comme ceci:

class Program
{
    static void Main(string[] args)
    {
        Person person1 = new Person("Kate","Middleton",null);
    }
}

ou comme ceci:

class Program
{
    static void Main(string[] args)
    {
        Person person1 = new Person();
        person1.FirstName = "Kate";
        person1.LastName = "Middleton";
    }
}

Je me demande également comment je devrais traiter les propriétés facultatives de la classe. Une fois les champs renseignés, comment puis-je les sauvegarder dans la base de données? J'ai une classe DatabaseComponenet pour enregistrer les informations. Comment puis-je gérer les options lors de l'enregistrement dans la base de données?

Alors, est-ce que je ferais quelque chose comme ça:

public int Save()
{
    int personId;
    personId = DatabaseComponent.InsertPerson(FirstName, LastName, DateOfBirth);
    return personId;
}

Merci pour toute aide! Quelques URL utiles sur la bonne conception de classe seraient également appréciées.

22
Mark Allison

Premièrement, je mettrais deux constructeurs publics distincts dans Person:

namespace BusinessLayer
{
    class Person
    {
        public Person(string firstName, string lastName): this(firstName, lastName, DateTime.Now)
        {}

        public Person(string firstName, string lastName, DateTime birthDate)
        {
            FirstName = firstName;
            LastName = lastName;
            DateOfBirth = birthDate;
        }

        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DateOfBirth { get; set; }
    }
}

cela vous permet d'écrire les deux 

var p = new Person("Marilyin", "Manson");
var p2 = new Person("Alice", "Cooper", new DateTime(...));

et

var p = new Person { FirstName="Marilyn", LastName="Manson" };

Je ne vois pas pourquoi vous devriez limiter à un seul formulaire.

En ce qui concerne DatabaseComponent, je vous suggère fortement d'écrire une méthode vous permettant de sauvegarder une personne au lieu de la signature que vous déclarez implicitement.

En effet, si un jour devait changer la définition d'une personne, vous devriez probablement changer le code à chaque fois que vous appelez la méthode Save(). En enregistrant simplement une personne, il vous suffit de modifier l'implémentation de Save().

Ne comptez-vous pas utiliser un ORM en passant?

18
Simone

Avec les initialiseurs de classe C # 3.0, je n'ai plus la peine de fournir un constructeur qui me permet d'initialiser toutes les propriétés

var person1 = new Person
{
    FirstName = "Kate";
    LastName = "Middleton";
};

En ce qui concerne la méthode Save, je les mets généralement dans une classe de référentiel séparée:

public int Save(Person person) 
{
    ...
}

et puis quand j'ai besoin de sauver une personne je fais:

var person1 = new Person
{
    FirstName = "Kate";
    LastName = "Middleton";
};
var id = new PersonsRepository().Save(person1);
10
Darin Dimitrov

N'utilisez les constructeurs que si certains champs sont obligatoire, car c'est un moyen efficace de s'assurer que ces champs sont spécifiés.

Je ne sais pas si les champs doivent être publics ou non

Les champs désignent généralement des variables membres et celles-ci doivent toujours être privées. En ce qui concerne les propriétés je voudrais coller avec get/set pour les objets de base de données.

Je me demande également comment je devrais traiter les propriétés facultatives de la classe. Une fois les champs renseignés, comment puis-je les sauvegarder dans la base de données? 

Enregistrer des éléments dans la base de données est une tout autre histoire. Je n'essaierais pas d'inventer ma propre couche mais d'utiliser une couche existante. Il existe tout un ensemble d’ORM: s du plus simple au plus complet.

Jetez un coup d'œil à PetaPoco pour une alternative légère ou nHibernate pour une alternative plus complète.

Validation

Un moyen courant de s'assurer que les champs obligatoires sont correctement spécifiés et que des valeurs valides sont obtenues consiste à utiliser un cadre de validation. Il existe un fichier intégré dans .net appelé DataAnnotations . Google et regarder quelques exemples.

5
jgauffin

Cela devrait être vérifié en utilisant des règles métier.

Je veux dire que si vous voulez un modèle commercial très réutilisable, les objets métier doivent être réutilisés ailleurs, dans différentes zones. Cela peut signifier que la même classe "A" pourrait convenir à l'état "X" dans certaines activités, mais dans une autre situation. , même classe "A", ira bien dans l'état "Y".

Il existe un bon modèle de conception vous permettant d'implémenter des validateurs métier appelés Specification:

Cela peut être mis en œuvre de nombreuses façons, mais l'une des plus compactes consiste à créer des règles avec des expressions lambda.

Par exemple:

someAInstance => someAInstance.Name != null && someAInstance.Age > 30

Une autre solution consiste à utiliser des bibliothèques de validation d’objet existantes, telles que NHibernate Validator, qui peuvent être utilisées indépendamment sans NHibernate et vous permettent de définir des attributs dans les propriétés de classe telles que [NotNull], [NotNullNotEmpty] et des règles plus complexes. Vous pouvez également utiliser des règles intégrées ou vous pouvez construire les vôtres.

Pour en savoir plus, lisez cet article (vous y trouverez une liste de règles de validation prêtes à l'emploi)}

Notez que l’un des avantages les plus importants de NH Validator est qu’il peut être utilisé dans n’importe quelle couche, pas seulement dans les données ou dans la couche métier, et comme vous pouvez l’utiliser sans NHibernate, vous bénéficiez d’une interface légère, simple et conviviale. - validateur d'objets en couches.

0