2010-12-10 6 views
0

私はObj-CでNSComparisonMethodsプロトコルの最初の6つの機能を実装しようとしています。私は、次の@interface他の方法を実装するための作業方法を使用していますか?

@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 

さて、私はプロトコルから実施している機能はisEqualToあるがありフラクションオブジェクトのためにそれらを実装しています。単純に1つを使用するか、この場合2つの作業方法を使用して残りの部分を実装するのは良いプログラミング方法ですか?

次のようにこれらのメソッドのための私の実装は次のとおりです。

// 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]); 
} 

そして、次のように私の比較機能は次のとおりです。

-(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; 
    } 
} 

すべてのこれらの関数は一種の冗長であると、私はさまざまな方法があります確信していますそれらを実装する。私は教授が生徒をすべてゼロから始めるようにするのに使用された日に戻ったことを思い出しますが、再利用コードの考え方に反するものではありませんか?

答えて

0

可能な限り再利用する必要があります。

このような比較、何かにすべてのあなたの肉を入れてください:

-(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; 
    } 
} 

私はあなたの比較でやろうとしたのかわからなかったので、私は、私はあなたがしようとしなければならないと思ったものに基づいて1を書きましたする。分数を比較するには、それらを浮動小数点数に解決するだけです。それを行う最も簡単な方法は、分子/分母でなければなりません。 1/4 = 0.25と2/8 = 0.25なので、最大の共通分母を見つける必要はありません。私があまり単純化しなかったら、申し訳ありません。特に0の分母を使って関数を作成できるようにするなら(おそらくそうはならないはずです)、ここでは0で除算する必要があります。あなたがすべてでそれらを必要とする場合

次に使うには、他人を実装するための比較:

-(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

私はいつも==がfloat値のために使用すべきではないと思いました。 –

+0

これは大雑把なルールですが、真実==は[a isEqual:b]と正確に等価です。そのような概念を回避するには、「演算子」の内部が間違った場所です。 [isEqual:b within:margin]を気にするなら、それも実装してください! –

関連する問題