2010-12-10 48 views
0

J'ai travaillé sur l'implémentation des 6 premières fonctions du protocole NSComparisonMethods dans Obj-C. Je leur mise en œuvre pour un objet Fraction qui a les éléments suivants @interfaceEst-ce que l'utilisation d'une méthode de travail pour mettre en œuvre d'autres bonnes pratiques de programmation?

@interface Fraction : NSObject <NSComparisonMethods> { 
    int numerator; 
    int denominator; 
} 
@property int numerator, denominator; 
+(int)addCounter; 
-(Fraction *)addWithCount:(Fraction *)f; 
-(void)print; 
-(void)setTo:(int)n over:(int)d; 
-(double)convertToNum; 
-(int)gcd:(int)d1:(int)d2; 
-(int)compare:(Fraction *)f; 
// NSComparisonMethods Protocol Methods 
-(BOOL)isEqualTo:(Fraction *)f; 
-(BOOL)isLessThanOrEqualTo:(Fraction *)f; 
-(BOOL)isLessThan:(Fraction *)f; 
-(BOOL)isGreaterThan:(Fraction *)f; 
-(BOOL)isGreaterThanOrEqualTo:(Fraction *)f; 
-(BOOL)isNotEqualTo:(Fraction *)f; 
@end 

Maintenant, la fonction que j'ai mis en œuvre à partir du protocole est isEqualTo. Est-ce une bonne pratique de programmation d'en utiliser simplement un ou, dans ce cas, deux méthodes de travail pour mettre en œuvre le reste?

Ma mise en œuvre de ces méthodes est la suivante:

// NSComparisonMethods Protocol Methods 
-(BOOL)isEqualTo:(Fraction *)f{ 
    [self reduce]; 
    [f reduce]; 
    return ((self.numerator==f.numerator)&&(self.denominator==f.denominator)); 
} 
-(BOOL)isLessThan:(Fraction *)f{ 
    return ([self compare:f]==-1); 
} 
-(BOOL)isLessThanOrEqualTo:(Fraction *)f{ 
    return (([self compare:f]==-1) || ([self isEqualTo:f])); 
} 
-(BOOL)isGreaterThan:(Fraction *)f{ 
    return ([self compare:f]==1); 
} 
-(BOOL)isGreaterThanOrEqualTo:(Fraction *)f{ 
    return (([self compare:f]==1) || ([self isEqualTo:f])); 
} 
-(BOOL)isNotEqualTo:(Fraction *)f{ 
    return (![self isEqualTo:f]); 
} 

Et ma fonction de comparaison est la suivante:

-(int)compare:(Fraction *)f{ 
    int value = [self gcd:denominator :f.denominator]; 
    if ([self isEqualTo:f]) { 
     return 0; 
    } else if ((numerator * (f.denominator/value))>(f.numerator * (denominator/value))) { 
     return 1; 
    } else { 
     return -1; 
    } 
} 

Toutes ces fonctions sont un peu redondant et je suis sûr qu'il ya différentes façons pour les mettre en œuvre. Je me souviens qu'à l'époque les professeurs avaient l'habitude de faire en sorte que les élèves fassent tout comme si c'était à partir de zéro, mais cela ne va-t-il pas à l'encontre de la mentalité de code que nous devrions tous utiliser?

Répondre

0

Vous devriez réutiliser autant que possible.

Mettez toutes vos viandes en comparaison, quelque chose comme ceci:

-(NSComparisonResult)compare:(Fraction *)f{ 
    float myValue = ((float)numerator/denominator); 
    float theirValue = ((float)f.numerator/f.denominator); 
    if (myValue == theirValue) { 
     return NSOrderedSame; 
    } else if (myValue > theirValue) { 
     return NSOrderedDescending; 
    } else { 
     return NSOrderedAscending; 
    } 
} 

Je ne savais pas ce que vous essayez de faire dans votre comparaison, j'ai donc écrit un basé sur ce que je pensais que vous devriez essayer faire. Pour comparer les fractions, tout ce que vous devez faire est de les résoudre en float. Le moyen le plus simple de le faire devrait être le numérateur/dénominateur. Il ne devrait pas être nécessaire de trouver le plus grand dénominateur commun, puisque 1/4 = 0,25 et 2/8 = 0,25. Si j'ai trop simplifié, désolé. Si vous autorisez la création de fonctions avec un dénominateur de 0 en particulier (vous ne devriez probablement pas le faire), vous devrez vous prémunir contre une division par zéro ici.

Utilisez ensuite comparer pour mettre en œuvre les autres, si vous avez besoin du tout:

-(BOOL)isEqualTo:(Fraction *)f{ 
    return ([self compare:f] == NSOrderedSame); 
} 
-(BOOL)isLessThan:(Fraction *)f{ 
    return ([self compare:f] < NSOrderedSame); 
} 
-(BOOL)isLessThanOrEqualTo:(Fraction *)f{ 
    return ([self compare:f] <= NSOrderedSame); 
} 
-(BOOL)isGreaterThan:(Fraction *)f{ 
    return ([self compare:f] > NSOrderedSame); 
} 
-(BOOL)isGreaterThanOrEqualTo:(Fraction *)f{ 
    return ([self compare:f] >= NSOrderedSame); 
} 
-(BOOL)isNotEqualTo:(Fraction *)f{ 
    return ([self compare:f] != NSOrderedSame) 
} 
+0

J'ai toujours pensé que == ne doit pas être utilisé pour les valeurs flottantes. –

+0

C'est une bonne règle, mais sincèrement == est * exactement * l'équivalent de [a isEqual: b]. A l'intérieur de "l'opérateur" est le mauvais endroit pour contourner des concepts comme ça. Si vous vous souciez de [a isEqual: b within: margin], implémentez cela aussi! –