2009-10-18 18 views
4

Je suis un peu confus en ce qui concerne la programmation orientée objet pour une application à 3 niveaux, par exemple. Voici juste un petit exemple de ce que j'essaie de faire (je vais raccourcir la conception de la base de données pour le rendre simple). Supposons que je fais un système de help desk de billet. Un ticket a une description, une personne responsable, une date d'échéance, et bien sûr un identifiant (unique).Comment définir l'ID dans le code orienté objet

Supposons que l'ID est juste une colonne IDENTITY de type integer et obtient sa valeur automatiquement (SQL Server). C'est-à-dire qu'il obtient sa valeur seulement après qu'une insertion a été faite.

Maintenant, juste un exemple de pseudo-code (il peut ne pas être correct, alors ne laissez pas la syntaxe vous déranger, juste essayer d'obtenir une réponse sur la façon de stocker l'ID).

Je pourrais facilement créer une classe de billets

public class Ticket 
{ 
    private string m_description; 
    private date m_duedate; 
    private string m_responsible; 
    private int m_id; //should this be read only ??? or...how 

    //then I can have a bunch of Properties to get/set these private variables 
    public Property Responsible{ 
     get 
      { return m_responsible; } 
     set 
      { m_responsible = value; } 
    } 

    //and so on..again dont worry about syntax. Now should I have a get/set for the ID? 
} 

Ok donc j'ai cette classe appelée ticket..but ce qui se passe lorsque je crée un objet de billets et besoin pour l'insérer de mon BLL (couche logique métier)

Bll b = new Bll(); 
    Ticket t = new Ticket(); 
    t.Responsible = someString; 
    t.DueDate = someDate; 
    t.Description = someLongString; 
    //use the BLL to create a ticket object and pass it to the DAL ? 
    //then assign the ID from the database to t.ID ??? 
    t.ID = bll.InsertTicket(t); 

// qui est passer à la BLL, qui fait son travail, et il passe à la DAL fait une instruction INSERT puis retourne le numéro d'identification donné par la base de données.

Donc, ma question est de savoir comment ou quand dois-je attribuer t.ID ou dois-je même donné après son insertion, je suis fait. Je suis toujours confondu avec la POO parce que j'ai tendance à penser que cela complique les choses plus que simplement passer tout un tas de paramètres.

Ok, donc après quelqu'un peut m'aider à comprendre si j'ai besoin d'un get/set sur l'ID et si je devrais transmettre cette valeur à mon interface. Ma deuxième question concerne les mises à jour? Supposons qu'un utilisateur final trouve un ticket, donc sur mon interface je récupère des données de ticket et quelqu'un veut mettre à jour dites la description et la date d'échéance. Lorsque je "Soumets" ces changements, devrais-je simplement créer un objet ticket, définir toutes les valeurs de propriété get/set et c'est tout? Ou devrais-je simplement passer le numéro d'identification et tous les paramètres à mon BLL et le laisser manipuler tout cela?

J'espère que tout cela a du sens!

Merci beaucoup les gars!

+0

Édition de @Peter Lillevold: "orienté" est l'orthographe britannique la moins utilisée; Ce n'est pas une erreur. –

Répondre

1

La réponse est que cela dépend de la structure ou de la bibliothèque que vous utilisez.

Tous les BLL ne vous permettent pas simplement de dire Ticket t = new Ticket(), vous devrez peut-être utiliser t = b.CreateTicket() ou quelque chose comme ça. L'ID peut être une valeur temporaire ou simplement null/0 jusqu'à ce qu'il soit conservé.

Sur la deuxième partie de votre question:

Si vous souhaitez mettre à jour un billet vous avez certainement ne créer un nouvel objet de billets. Vous mettez à jour l'objet existant.

Peut-être que vous devriez clarifier ou poser à nouveau la question à la lumière d'une bibliothèque ou d'une technologie spécifique.

+0

Désolé, cela n'a pas de sens. Pourquoi créez-vous un ticket à partir de la couche Logique métier? Pour moi, vous créez simplement l'objet ticket, puis vous le transmettez à la BLL pour créer le ticket. Peu importe le cadre dans lequel vous êtes. Juste un rappel que lorsque j'ai dit Ticket t = new Ticket(); J'étais certainement pas dans le BLL du code. J'étais sur le programme final si c'est une interface web ou une interface client. J'instancie l'objet de type ticket.Définissez ses propriétés, puis passez-le à la couche logique métier pour créer le ticket. Mais ma question n'a toujours pas de réponse. L identité? – user192059

+0

J'ai dit _some_ libs ne vous laissera pas créer des objets directement. D'autres le feront. Une raison pour la restreindre est que la BLL ou la DAL veut créer l'ID. –

+0

Ok Henk suppose que c'est C#. Je suppose que ma question est, est ma logique ok. Est-il sûr de créer une propriété en lecture/écriture appelée ID? Ensuite, j'instancie un objet ticket, définissez ses propriétés et le transmettez à la BLL en tant qu'objet ticket. À son tour, le BLL passe l'objet ticket à mon DAL. Ma DAL accède aux propriétés de l'objet ticket et insère un ticket dans une table SQL et renvoie l'IDentifier à la BLL qui, en retour, le renvoie à mon interface client. Cette valeur renvoyée peut être t.ID = b.CreateTicket (t). Cela signifie qu'il affectera la valeur de la propriété db à la propriété t.ID. Est-ce correct ? – user192059

1

Normalement, j'utiliserais une certaine valeur de clé (c'est-à-dire -1) comme ID non sauvegardé par défaut. Ceci serait ensuite transmis en amont à la couche DB concernée qui enregistrerait cet objet et mettrait à jour les ID et les renverrait si nécessaire (sinon, la demande du client final serait mise à jour si nécessaire). J'ai souvent la valeur par défaut de la clé sur la construction de l'objet. Dans certains projets précédents, j'ai utilisé Guid comme clés car elles peuvent être générées sur le serveur client/application sans que la base de données soit requise pour la génération de clé (et la mise à jour ultérieure des clés étrangères vers les objets parents). Cela peut économiser beaucoup de temps en termes d'exécution du SQL, car il peut être plus facile à effectuer par lot). Un peigne de guidage pourrait être utilisé pour une génération plus rapide des clés si nécessaire. Cependant, cela pourrait ne pas être une option si vous avez besoin de clés incrémentielles.

Cela pourrait varier en fonction de cadres/technologies/infrastructures ...

+0

Ok Je comprends donc il est sûr de supposer que je pourrais créer une propriété en lecture/écriture appelée ID dire. Et une fois que je fais quelque chose comme ceci: ticket t = new Ticket(); le constructeur par défaut pourrait définir cet ID à -1. Ensuite, je remplis le reste des propriétés et le passe à la couche logique métier en tant que paramètre d'objet ticket? Et puis à l'intérieur de ma BLL je peux le passer à ma couche db comme un paramètre d'objet de billet? Est-ce correct que je passe le même objet ticket du code client, à la BLL à la DAL. Puis-je accéder aux propriétés et insérer le ticket en tant qu'enregistrement via un sproc et un identifiant de retour? – user192059

0

Utilisez NHibernate ou autre O/R Mapper décent, et vous aurez même pas ce problème. La propriété peut être en lecture seule et définie par l'ORM lui-même avant ou juste après l'insertion. Sauf que, si vous le faites à la main, vous pouvez le faire en lecture seule et utiliser une petite quantité de réflexion pour définir l'ID de la DAL si nécessaire sans enfreindre l'encapsulation. En aparté, pourquoi passez-vous l'objet à une BRL? L'objet lui-même ne devrait-il pas mettre en œuvre sa propre logique métier? C'est le point de faire des objets. Sinon, vous devez simplement utiliser des jeux de données fortement typés. On dirait que vous faites le « modèle de domaine anémique » qui est mauvais:

http://martinfowler.com/bliki/AnemicDomainModel.html

+0

Sinon, comment pourrais-je obtenir cet objet de ticket à la couche d'accès aux données (DAL). L'interface n'a aucun moyen d'accéder à la couche DAL, uniquement via la couche de distribution – user192059

0

cette annonce Peut-être vous aidera à:

public class Ticket : IEquatable<Ticket> 
    { 

    public static Ticket Create() 
    { 
      return new Ticket { Id = Guid.NewGuid() }; 
    } 

    /// Id must be really unique 
    public Guid Id {get; private set;} 

    /// other properties 
    /// ... 

    bool IEquatable.Equals(Ticket ticket) 
    { 
      return ticket != null && ticket.Id == this.Id; 
    } 

    /// hidden ctor 
    protected Ticket() {} 
    } 
0

Vous pouvez essayer quelque chose comme ça. Le code n'est pas parfait, mais ça vous donnera une idée. Désolé, j'essaye de faire ceci plus rapidement que je devrais, donc c'est très dur.

// returns Record number of object 
public int Insert() 
{ 
    SqlConnection conn = new SqlConnection(dbstring); 
    SqlCommand insertCommand = new SqlCommand("mystoredprocedure"); 
    SqlParameter newRecNo = new SqlParameter(); 
    newRecNo.Direction = ParameterDirection.ReturnValue; 
    conn.Open(); 
    insertCommand.ExecuteNonQuery(); // Your sqlparameter will now contain the recno 
    conn.close(); // use try/catch, etc. 
    return newRecNo.value; 
} 
public static MyObject GetData(int TicketID) 
{ 
    // Get object data from DB. 
} 

In the stored procedure to insert, put this in: 

declare @recno int 
set @recno = @@identity 
return @recno 
0

Quelques points:

1 - La notation hongroise est sooo 1985 mec. :)

2 - Vous réinventez la roue ici. Il y a beaucoup de bons ORM frameworks qui gèrent la persistance de manière standardisée et vous permettent d'écrire votre domaine.

3 - Ok, donc si vous ne pouvez absolument pas utiliser un framework ORM comme NHibernate, ou, Dieu nous en plait, Entity Framework, alors je vous suggère de respecter l'un des modèles standard que les frameworks ORM utilisent, comme ActiveRecord ou DataMapper. Oui, vous devez affecter le Identity Field après la persistance d'un nouvel objet. Les modèles ActiveRecord et DataMapper de Martin Fowler utilisent tous les deux une méthode 'insert' pour conserver les nouveaux objets dans la base de données. Dans d'autres frameworks ORM comme Rails, une méthode similaire, 'save' est utilisée, et un nouvel objet peut signaler s'il a été persistant en appelant une interface telle que 'new_record?' qui retourne TRUE jusqu'à ce que 'save' ou 'insert' soit appelé. Jusqu'à ce que l'une de ces méthodes soit appelée, le champ ID est généralement défini par défaut sur 0 ou -1, les deux PKID non valides. Dans 'insert' ou 'save', le nouveau champ id est récupéré et affecté au champ id du nouvel objet.

Questions connexes