Методология проектирования API-оболочки Objective-C - PullRequest
3 голосов
/ 17 марта 2010

Я знаю, что нет единого ответа на этот вопрос, но я хотел бы узнать мнение людей о том, как они будут подходить к ситуации.

Я пишу оболочку Objective-C в библиотеку C. Мои цели:

1) Оболочка использует объекты Objective-C. Например, если C API определяет параметр, такой как char * name, Objective-C API должен использовать name: (NSString *).

2) Клиент, использующий оболочку Objective-C, не должен знать о внутреннем функционировании библиотеки C.

Скорость на самом деле не проблема.

Все просто с простыми параметрами. Конечно, нет проблем взять NSString и преобразовать его в строку C, чтобы передать ее в библиотеку C.

Моя нерешительность проявляется, когда речь идет о сложных структурах.

Допустим, у вас есть:

struct flow
{
    long direction;
    long speed;
    long disruption;
    long start;
    long stop;
} flow_t;

And then your C API call is:

void setFlows(flow_t inFlows[4]);

Итак, некоторые из вариантов:
1) предоставить клиенту структуру flow_t и заставить Objective-C API принять массив этих структур
2) построить NSArray из четырех NSDictionaries, содержащих свойства, и передать его в качестве параметра
3) создать NSArray из четырех объектов «Flow», содержащих свойства структуры, и передать его в качестве параметра

Мой анализ подходов:
Подход 1: самый простой. Тем не менее, это не соответствует целям дизайна
Подход 2: По какой-то причине, мне кажется, это самый "Objective-C" способ сделать это. Однако каждый элемент NSDictionary должен быть обернут в NSNumber. Теперь кажется, что мы делаем очень много, просто чтобы передать эквивалент структуры.
Подход 3: кажется мне наиболее чистым с объектно-ориентированной точки зрения, и дополнительная инкапсуляция может пригодиться позже. Однако, как и в случае с №2, теперь кажется, что мы делаем очень много (создаем массив, создаем и инициализируем объекты) просто для передачи структуры.

Итак, вопрос в том, как бы вы подошли к этой ситуации? Есть ли другие варианты, которые я не рассматриваю? Есть ли дополнительные преимущества или недостатки в подходах, которые я представил, которые я не рассматриваю?

Ответы [ 4 ]

2 голосов
/ 17 марта 2010

Я думаю, что подход 3 был бы предпочтительным способом сделать вещи.Когда вы оборачиваете библиотеку, вы захотите создать обертки вокруг любого объекта или структуры, с которыми, как ожидается, будет иметь дело пользователь.

Если вы все обернете, тогда вы сможете изменить внутреннюю работу ваших классов вболее поздняя дата, не затрагивая интерфейсы, к которым привыкли ваши пользователи.Например, в будущем вы, возможно, поймете, что хотели бы добавить какой-либо тип проверки или исправления ошибок ... возможно, установка stop более ранняя, чем start, вызывает некоторые ошибки вычисления, вы можете изменить *Метод 1005 * в вашей обертке Flow устанавливает start равным stop, если stop меньше start (я признаю, это очень плохой пример).

2 голосов
/ 17 марта 2010

Я бы придерживался подхода 3. Вы «просто передаете структуру» сейчас , но объект Flow может расшириться в будущем. Вы говорите, что скорость не является проблемой, и поэтому я предполагаю, что потребление памяти также не является, или вы все равно будете придерживаться C.

1 голос
/ 18 марта 2010

Мой ответ не тот, что вы спрашивали, но я все еще "как бы подхожу к ситуации".

Первый вопрос, который я хотел бы задать: "Какую ценность добавляет эта оболочка?" Если ответ «использовать синтаксис Objective-C», тогда ответ «не меняйте ничего, используйте библиотеку как есть, потому что C - это синтаксис Objective-C».

Я не знаю, какую библиотеку вы упаковываете, поэтому я буду использовать SQLite в качестве примера. Используя многоуровневый подход, я бы сделал что-то вроде этого:

A) Объекты высокого уровня (Заказ, Заказчик, Поставщик ...)

Б) Базовый класс (Запись)

C) SQLite

Таким образом, базовый класс написан для непосредственного вызова SQLite, тогда как другие классы работают как обычные классы Objective-C.

Это относится к:

1) Объекты высокого уровня (Заказ, Заказчик, Поставщик ...)

2) Базовый класс (Запись)

3) SQLite Wrapper (Objective-C)

4) SQLite

Создается то же приложение, но есть дополнительная работа по созданию, поддержанию и отладке уровня 3, при этом очень мало чего можно показать.

В первой версии слой B обернул SQLite, так что ничто над ним не вызывало SQLite напрямую И он не пытался обеспечить все функциональные возможности SQLite. Он просто обеспечивает функциональность, необходимую для уровня A, и использует SQLite для достижения того, что необходимо. Он «оборачивает» SQLite, но более специфично для приложения. Этот же класс Record может быть повторно использован в другом приложении позже и расширен для удовлетворения потребностей обоих приложений в то время.

0 голосов
/ 17 марта 2010

Так как Objective-C использует структуры, почему бы не оставить его как структуру типа NSRect ?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...