2012-05-10 11 views
9

Załóżmy, że tworzę klasę Objective-C reprezentującą ułamek i chcę tworzyć niezmienne i zmienne wersje.Jaki jest najskuteczniejszy sposób tworzenia niezmiennych i zmiennych wersji klasy-c?

Zgodnie ze wzorami w strukturze Foundation, można spodziewać się metody fractionByAddingFraction: w wersji niezmiennej i addFraction: w wersji zmiennej.

Paradoks, na który napotykam, to sposób włączenia logiki dodawania ułamków tylko między dwie klasy. Wydaje się, że niezmienna metoda musi znać (i wykorzystywać) zmienną metodę, aby uniknąć powielania kodu, a jednak zawierająca zmienne metody w implementacji niezmiennej klasy oznacza, że ​​mogłyby one być wywołane na niezmiennym obiekt, który pokonuje punkt.

Krótkie wyjaśnienie (lub lepiej, kontynuacja tego uproszczonego przykładu) byłoby bardzo docenione!

+4

Twój przykład klasy wydaje się reprezentować _value object_, więc nie sądzę, że powinieneś podać dla niego zmienną wersję. __Tylko zmień go na niezmienny .__ –

+0

@ Jordão Na ten konkretny przykład masz całkowitą rację. Po prostu uważałem, że jest to najłatwiejszy i najbardziej zwięzły sposób na wyjaśnienie mojego nieporozumienia na temat pojęcia w ogóle (ponieważ dotyczy to bardziej skomplikowanych klas). Jakieś przemyślenia na temat tego, jak to się stanie, niezależnie od tego? – user1385983

Odpowiedz

3

Twoje podejście jest poprawne (jeśli naprawdę potrzebujesz zmiennej podklasy, której powinieneś unikać, chyba że naprawdę tego potrzebujesz). Nie jestem całkiem pewien, skąd się bierze zamieszanie. Najłatwiej byłoby zaimplementować addFraction: przy użyciu fractionByAddingFraction:. Byłoby to trochę nieefektywne, ale taki kierunek miałby największy sens. Coś jak:

- (void)addFraction:(Fraction *)anotherFraction { 
    Fraction *newFraction = [self fractionByAddingFraction:anotherFraction]; 
    self.internalStuff = newFraction.internalStuff; 
} 

Ale zazwyczaj ty pewnie to bardziej efektywnie poradzić z jakimś prywatnym _GetInternalStuffByAddingInternalStuffs() funkcji, że obie klasy byłoby wykorzystać.

+0

Dzięki za sugestie. Uniknąłem pierwszego podejścia, ponieważ, jak wspomniałeś, może być nieefektywne tworzenie nowego obiektu za każdym razem, gdy którykolwiek z jego składników zostanie zmieniony. Twój pomysł stworzenia prywatnej funkcji wydaje się być dobrą alternatywą, jednak zastanawiam się, gdzie najlepiej byłoby zlokalizować tę funkcję, aby była dostępna dla obu implementacji klas, ale niedostępna dla niczego innego (co wyklucza umieszczenie jej w nagłówku)? – user1385983

+0

Zwykle robi się to z prywatnym nagłówkiem, takim jak Fraction + Private.h. Zauważ, że nadal możesz chcieć rozważyć utratę mutabilnej formy, jeśli jest to coś takiego. Zwróć uwagę, że NSNumber nie ma zmiennej postaci. Jeśli nie tworzysz wielu z nich bardzo szybko, prostota i bezpieczeństwo nici obiektów wartościowych czyni je bardzo atrakcyjnymi. Nawet jeśli robisz je bardzo szybko, możesz niektóre z nich przechować w pamięci podręcznej. NSNumber buforuje liczby całkowite -1-12 jako pojedyncze, jak pamiętam. Możesz zrobić tego rodzaju buforowanie najłatwiej z niezmiennymi obiektami. Ale powyższe jest, jak sobie z tym radzisz, gdy potrzebujesz zmiany. –

+0

Pamiętaj, że możesz zajrzeć i sprawdzić, jak zaimplementowane są podstawowe obiekty CoreFoundation: http://opensource.apple.com/source/CF/CF-635/CFArray.c. –

0

Podstawowe implementacje oszukiwania kolekcji Fundacji: istnieje tylko jedna implementacja, która jest podklasą NSMutableFoo, i ma prywatną flagę zmienności. Oznacza to, że kod klienta nie może sprawdzić, czy dany obiekt jest zmienny czy nie, ale i tak nigdy nie byłby to dobry pomysł, z wyjątkiem może debugowania i zapewnień.

+0

Czy poprawnie rozumiem, że "NSFoo" byłaby podklasą "NSMutableFoo", a "NSMutableFoo" zawierałoby wszystkie metody dla obu klas, jednak ograniczyć jego niezmienną podklasę "możliwość używania tych zmiennych w oparciu o prywatną flagę? – user1385983

+0

'NSFoo' nie jest podklasą' NSMutableFoo', no. Relacja jest ogólnie 'NSFoo' ←' NSMutableFoo' ← 'NSCFFoo', gdzie' NSCFFoo' jest konkretną implementacją. Metody mutowania NSCFFoo' sprawdzają flagę zmienną i wyrzucają wyjątek, jeśli jest niezmienny. (Rzeczywistość jest w rzeczywistości bardziej skomplikowana niż z powodu bezpłatnego mostkowania, ale tak to działałoby bez udziału CF.) Dla własnych klas prawdopodobnie nazwałbyś konkretną podklasę czymś w rodzaju 'XYConcreteFoo'. –

Powiązane problemy