2012-05-10 2 views
9

Предположим, что я создаю класс Objective-C, представляющий дробь, и хочу создавать неизменяемые и изменяемые версии.Каков наиболее эффективный способ создания неизменяемых и изменяемых версий класса object-c?

Следуя шаблонам в рамках Foundation, вы можете ожидать, что в неизменяемой версии можно найти метод fractionByAddingFraction: и addFraction: в изменяемой версии.

Парадокс, с которым я столкнулся, заключается в том, как только включить логику добавления долей между двумя классами. Кажется, что неизменяемый метод fractionByAddingFraction: должен знать о (и использовать) метод изменчивого addFraction: во избежание дублирования кода, и все же включать в себя изменяемые методы при реализации неизменяемого класса означает, что их можно было бы, вероятно, вызвать на неизменяемом объект, который побеждает точку.

Краткое описание (или, еще лучше, продолжение этого упрощенного примера) было бы высоко оценено!

+4

Пример вашего класса, похоже, представляет объект _value_, поэтому я не думаю, что вы должны предоставить ему изменяемую версию. __Просто сделайте его неизменным .__ –

+0

@ Jordão Для этого конкретного примера вы совершенно правы. Я просто почувствовал, что это самый простой и кратчайший способ объяснить мое замешательство в отношении концепции вообще (поскольку она относится к более сложным классам). Любые мысли о том, как это будет сделано независимо? – user1385983

ответ

3

Ваш подход правильный (если вам действительно нужен изменяемый подкласс, который следует избегать, если он вам действительно не нужен). Я не совсем понимаю, где возникает путаница. Вы бы максимально легко использовали addFraction:, используя fractionByAddingFraction:. Это было бы немного неэффективно, но это направление, которое имеет наибольший смысл. Что-то вроде:

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

Но, как правило, вы, вероятно, справиться с этим более эффективно с некоторой частной _GetInternalStuffByAddingInternalStuffs() функции, что оба класса будут использовать.

+0

Спасибо за предложения. Я избегал первого подхода просто потому, что, как вы уже упоминали, он может быть неэффективным для создания нового объекта каждый раз при изменении любого из его компонентов. Ваша идея создания частной функции кажется хорошей альтернативой, однако мне интересно, где функция идеально расположена, чтобы быть доступной для реализации обоих классов, но недоступной для чего-либо еще (что исключает возможность помещать ее в заголовок)? – user1385983

+0

Обычно это делается с закрытым заголовком, таким как Fraction + Private.h. Обратите внимание, что вы все равно можете рассмотреть возможность перекоса изменяемой формы, если это так. Обратите внимание, что NSNumber не имеет изменяемой формы. Если вы не создаете многие из них очень быстро, простота и безопасность потоков объектов ценности делают их очень привлекательными. Даже если вы делаете их очень быстро, вы можете кэшировать некоторые из них. Я помню, NSNumber кэширует целые числа -1-12 как одиночные. Вы можете сделать такое кэширование наиболее легко с неизменяемыми объектами. Но выше, как вы справляетесь с этим, когда вам нужна изменчивость. –

+0

Помните, что вы можете пойти и посмотреть, как реализуются базовые объекты CoreFoundation: http://opensource.apple.com/source/CF/CF-635/CFArray.c. –

0

Основные реализации коллекций фонда Cheat: существует только одна реализация, которая является подклассом NSMutableFoo и имеет свой собственный флаг мутности. Это означает, что клиентский код не может проверить, является ли конкретный объект изменчивым или нет, но это никогда не будет хорошей идеей, за исключением, возможно, для отладки и утверждений.

+0

Правильно ли я понимаю, что «NSFoo» будет подклассом «NSMutableFoo», и что «NSMutableFoo» будет содержать все методы для обоих классов, но ограничить его неизменную способность подкласса использовать изменчивые на основе частного флага? – user1385983

+0

'NSFoo' не является подклассом' NSMutableFoo', no. Взаимоотношение, как правило, «NSFoo» ← 'NSMutableFoo' ←' NSCFFoo', где 'NSCFFoo' является конкретной реализацией. «Мутирующие методы NSCFFoo» проверяют измененный флаг и генерируют исключение, если оно неизменное. (Реальность на самом деле сложнее, чем это из-за беспошлинного моста, но так оно и будет работать без участия CF.) Для ваших собственных классов вы, вероятно, называете конкретный подкласс чем-то вроде «XYConcreteFoo». –

 Смежные вопросы

  • Нет связанных вопросов^_^