2008-11-27 6 views
1

Je veux créer du code maintenable, mais cette situation d'héritage me cause des problèmes.Héritage classe class, comment faire de ce code maintenable

Le problème est lié à la deuxième classe d'assistance de base de données nommée InitUserExtension.

Étant donné que UserExtension hérite de l'utilisateur, je dois m'assurer que je miroir les modifications de mon assistant InitUser à InitUserExtension.

Je n'aime vraiment pas cela comme son enclin aux bugs, quelle est la solution?

Mes définitions de classe:

public class User 
{ 
    public string Name {get; set; } 
    public string Age { get; set; } 
} 

public class UserExtension : User 
{ 
    public string Lastname {get; set; } 
     public string Password {get; set; } 

} 

Mes assistants de base de données:

public static SqlDataReader InitUser(SqlDataReader dr) 
{ 
     User user = new User(); 

     user.Name = Convert.ToString(dr["name"]); 
     user.Age ... 
} 


public static SqlDataReader InitUserExtension(SqlDataReader dr) 
{ 
     UserExtension user = new UserExtension(); 


     // note: mirror attributes from User 
     user.Name = Convert.ToString(dr["name"]); 
     user.Age ... 



     user.Lastname = Convert.ToString(dr["lastname"]); 
     user.Password = ....; 
} 

Répondre

2

Que diriez-vous de déplacer le traitement de Name etc dans une méthode (acceptant un utilisateur ou un T: User), et appelez cela des deux?

private static void InitUser(User user, SqlDataReader dr) 
{ // could also use an interface here, or generics with T : User 
    user.Name = Convert.ToString(dr["name"]); 
    user.Age ... 
} 


public static User InitUser(SqlDataReader dr) 
{ 
    User user = new User(); 
    InitUser(user, dr); 
    return user; 
} 

public static UserExtension InitUserExtension(SqlDataReader dr) 
{ 
    UserExtension user = new UserExtension(); 
    InitUser(user, dr); 
    user.Lastname = Convert.ToString(dr["lastname"]); 
    user.Password = ....; 
    return user; 
} 

Comme alternative, vous pouvez réduire le nombre de lignes, mais augmenter la complexité, en utilisant les génériques:

private static T InitUserCore<T>(SqlDataReader dr) where T : User, new() 
{ 
    T user = new T(); 
    // ... 
    return user; 
} 
public static User InitUser(SqlDataReader dr) 
{ 
    return InitUserCore<User>(dr); 
} 
public static UserExtension InitUserExtension(SqlDataReader dr) 
{ 
    UserExtension user = InitUserCore<UserExtension>(dr); 
    // ... 
    return user; 
} 
+0

J'ai une méthode parseRow , alors je peux le dire dans quel but je veux créer et attribuer des valeurs à (à partir d'un lecteur ou tablerow) –

+0

@Andrew Bullock - comme la modification que je viens d'ajouter? –

1

Pourquoi appelez-vous pas InitUser de la méthode InitUserExtension. Laissez l'initialisation de base gérer les propriétés de la classe de base et laissez l'initialiseur étendu gérer les propriétés de la classe d'extension.

0

Je ne sais pas pourquoi vous ne l'avez pas placé le code d'assignation dans les catégories eux-mêmes, mais il peut avoir à faire avec la façon dont vous obtenez les informations à stocker ...

Ma solution serait de réécrire quelque chose comme:

public class User 
{ 
    public string Name {get; set; } 
    public string Age { get; set; } 

    public User(DataReader dr) 
    { 
     user.Name = Convert.ToString(dr["name"]); 
     user.Age ... 
    } 
} 

public class UserExtension : User 
{ 
    public string Lastname {get; set; } 
    public string Password {get; set; } 

    public UserExtension(DataReader dr):base(dr) 
    { 
     user.Lastname = Convert.ToString(dr["lastname"]); 
     user.Password = ....; 

    } 
} 

Milage peut varier en fonction de votre situation

De cette façon, un appel comme

var MyExtension = new UserExtension(dr); 

va remplir tous les champs correctement.

+0

Renommer le code db dans les classes: en guise de supposition ... persistance ignorance et séparation des préoccupations - c'est-à-dire qu'un POCO ne devrait pas avoir à connaître les détails de la base de données. –

+0

Hm, c'est vrai. Cependant, je ne vois pas comment il repasse les utilisateurs qu'il a créés dans le code de la base de données. S'il avait la déclaration en dehors des fonctions de la base de données et qu'il la transmettait, il pourrait aussi enchaîner les appels de fonction, assez facilement sans problème. – Wobin

1

Si vous préférez des aides font la même chose avec des aides

public class InitUser 
{ 
    public InitUser(SqlDataReader dr, User u) { } 
} 

public class InitUserExtension : InitUser 
{ 
    public InitUserExtension(SqlDataReader dr , UserExtension u) : base(dr, u) { } 
}