2010-05-11 3 views
1

J'ai mis en place un cours pour valider les numéros de cartes de crédit. Le type et le numéro de carte de crédit sont sélectionnés sur un formulaire dans une classe distincte. J'essaie de comprendre comment obtenir le type de carte de crédit et le numéro sélectionnés dans l'autre classe (frmPayment) pour ma carte de crédit algorithme de classe:Comment utiliser une classe distincte pour valider les numéros de cartes de crédit en C#

public enum CardType 
{ 
    MasterCard, Visa, AmericanExpress 
} 

public sealed class CardValidator 
{ 
    public static string SelectedCardType { get; private set; } 
    public static string CardNumber { get; private set; } 

    private CardValidator(string selectedCardType, string cardNumber) 
    { 
     SelectedCardType = selectedCardType; 
     CardNumber = cardNumber; 
    } 

    public static bool Validate(CardType cardType, string cardNumber) 
{ 
    byte[] number = new byte[16]; 


    int length = 0; 
    for (int i = 0; i < cardNumber.Length; i++) 
    { 
     if (char.IsDigit(cardNumber, i)) 
     { 
      if (length == 16) return false; 
      number[length++] = byte.Parse(cardNumber[i]); //not working. find different way to parse 
     } 
    } 

    switch(cardType) 
    { 
    case CardType.MasterCard: 
     if(length != 16) 
      return false; 
     if(number[0] != 5 || number[1] == 0 || number[1] > 5) 
      return false; 
     break; 

    case CardType.Visa: 
     if(length != 16 & length != 13) 
      return false; 
     if(number[0] != 4) 
      return false; 
     break; 

    case CardType.AmericanExpress: 
     if(length != 15) 
      return false; 
     if(number[0] != 3 || (number[1] != 4 & number[1] != 7)) 
      return false; 
     break; 

    } 

    // Use Luhn Algorithm to validate 
    int sum = 0; 
    for(int i = length - 1; i >= 0; i--) 
    { 
    if(i % 2 == length % 2) 
    { 
     int n = number[i] * 2; 
     sum += (n/10) + (n % 10); 
    } 
    else 
     sum += number[i]; 
    } 
    return (sum % 10 == 0); 

} }

Répondre

1

En frmPaymentsbtnValidate_click (ou similaire) gestionnaire d'événements, il suffit d'appeler CardValidator.Validate méthode.

Cependant, le constructeur CardValidator a des paramètres même si c'est privé, et jamais appelé? Et pourquoi avez-vous ajouté des propriétés à la classe? Edit: vous avez manqué quelques bits de votre exemple de code.

+0

+1 au deuxième paragraphe. Vous ne voulez probablement pas que le ctor prenne des args, puis les ignore peut-être dans la méthode. Si c'était moi, je rendrais le seul ctor privé, laisser tomber les deux propriétés, et garder la classe entière statique. Puis quand je voulais valider l'appel CardValidator.Validate (type, numéro); –

+0

ce n'est pas encore fini. J'arrivais juste là où je voulais commencer à essayer de l'appeler à partir de ma classe frmPayment, mais je n'arrivais pas à trouver un moyen de le faire. C'est pourquoi mon constructeur n'est pas encore là. Je n'ai pas fait un comme ça avant – EvanRyan

2

Pour commencer, j'utiliser Regex pour faire la simple validation (tous les chiffres, longueur spécifique.)

Mais au point de votre question, je ne suis pas sûr que je comprends ce que la question est. D'après ce que vous avez posté ici, il semble que vous devriez probablement laisser tomber le constructeur et rendre le tout une classe statique.

public enum CardType 
{ 
    MasterCard, 
    Visa, 
    AmericanExpress, 
} 

public static class CardValidator 
{ 
    public static bool Validate(CardType cardType, string cardNumber) 
    { 
     string strippedCardNumber = Regex.Replace(cardNumber, @"\D", String.Empty); 


     ICardValidator validator = SelectCardValidator(cardType); 

     return validator.Validate(strippedCardNumber); 
    } 

    private static ICardValidator SelectCardValidator(CardType cardType) 
    { 
     switch (cardType) 
     { 
      case CardType.MasterCard: 
       return new MasterCardValidator(); 
      case CardType.Visa: 
       return new VisaValidator(); 
      case CardType.AmericanExpress: 
       return new AmericanExpressValidator(); 
      default: 
       return new UnknownCardTypeValidator(); 
     } 
    } 

    private interface ICardValidator 
    { 
     bool Validate(string cardNumber); 
    } 

    private class UnknownCardTypeValidator : ICardValidator 
    { 
     #region ICardValidator Members 

     public bool Validate(string cardNumber) 
     { 
      return false; 
     } 

     #endregion 
    } 

    private abstract class LuhnAlgorithmValidator : ICardValidator 
    { 

     #region ICardValidator Members 

     public virtual bool Validate(string cardNumber) 
     { 
      // Implement Luhn Algorithm here 

      return false; 
     } 

     #endregion 
    } 

    private class MasterCardValidator : LuhnAlgorithmValidator 
    { 
     public override bool Validate(string cardNumber) 
     { 
      bool isValid = false; // replace with MasterCard validation 
      return isValid && base.Validate(cardNumber); 
     } 
    } 

    private class VisaValidator : LuhnAlgorithmValidator 
    { 
     public override bool Validate(string cardNumber) 
     { 
      bool isValid = false; // replace with Visa validation 
      return isValid && base.Validate(cardNumber); 
     } 
    } 

    private class AmericanExpressValidator : LuhnAlgorithmValidator 
    { 
     public override bool Validate(string cardNumber) 
     { 
      bool isValid = false; // replace with AmEx validation 
      return isValid && base.Validate(cardNumber); 
     } 
    } 
} 
+0

ouais, cela semble juste. Je suis toujours un programmeur très débutant, donc je fais encore assez souvent des erreurs assez basiques – EvanRyan

5

Vous manquez une excellente occasion pour un meilleur code POO et plus propre.

class CreditCard 
{ 
    public CreditCard(string number, string expiration, string cvv2) {...} 

    public virtual bool IsValid() 
    { 
     /* put common validation logic here */ 
    } 

    /* factory for actual cards */ 
    public static CreditCard GetCardByType (CardType card, string number, string expiration, string cvv2) 
    { 
     switch (card) 
     { 
      case CardType.Visa: 
        return new VisaCreditCard(...); 

      ... 
     } 
    } 
} 

class VisaCreditCard : CreditCard 
{ 
    public VisaCreditCard (string number, string expiration, string cvv2) 
     : base (number, expiration, cvv2) 
    {...} 

    public override bool IsValid() 
    { 
     /* check Visa rules... */ 
     bool isValid = ... 

     return isValid & base.IsValid(); 
    } 
} 
+0

Ceci est une solution vraiment propre. – Tyler

Questions connexes