2010-03-17 69 views
3

我知道这个问题没有人回答,但我想让人们考虑他们将如何处理这种情况。Objective-C封装API设计方法

我正在写一个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的四个NSDray,并将其作为参数传递给参数
3)创建一个包含结构属性的四个“Flow”对象的NSArray,我对方法的分析:
方法1:最简单。但是,它不符合设计目标。方法2:由于某种原因,这在我看来是最“目标C”的方式。但是,NSDictionary的每个元素都必须包装在一个NSNumber中。现在看来我们只是为了传递一个结构的等价物而做了很多事情。方法3:从面向对象的角度来看,似乎对我来说最清洁,而额外的封装可能会在以后派上用场。然而,就像#2一样,现在看起来我们正在做很多事情(创建一个数组,创建和初始化对象)只是为了传递一个结构。

所以,问题是,你会如何处理这种情况?我还没有考虑其他选择吗?我提出的方法有没有其他的优点或缺点,我不考虑?

+0

框架本身包含结构。 NSRange等。我认为在结构上没有一个通用的决定。这取决于。 – 2010-03-17 17:23:39

回答

2

我认为方法3是做事的首选方式。当你包装一个库时,你需要围绕用户需要处理的任何对象或结构创建包装。

如果你包装了所有东西,那么你可以随时改变你的类的内部工作,而不会影响你的用户习惯的接口。例如,将来您可能会意识到您想添加某种类型的错误检查或更正...如果stop小于start(我承认,这是一个非常糟糕的例子),也许设置stop早于start会导致一些计算错误,您可以更改流程包装中的stop方法设置start等于stop

+0

我同意。毕竟,初始化4个对象并将它们放入一个数组中并没有比初始化4个结构和将它们放入一个数组中更加不同,所以我认为我太担心了。 – wadesworld 2010-03-17 17:00:29

2

我会坚持做法3.您只是“传递结构”现在,但Flow对象可能在未来扩展更多。你说速度不是问题,所以我会想象内存消耗量不是,否则你会坚持使用C。

0

由于Objective-C使用结构,为什么不把它作为像NSRect这样的结构?

+0

因为它通常会更好地将结构体作为实际对象,因为您不能将结构体置于集合中(比如NSArrays),而无法先将它们装入“NSValue”对象中。 – 2010-03-17 17:00:31

1

我的回答不是你问的问题,但它仍然是我“如何处理这种情况”。

我会问的第一个问题是,“这个包装器添加了什么价值?”如果答案是“使用Objective-C语法”,那么答案是“不要改变一件事,按原样使用库,因为C是Objective-C语法。”

我不知道你打包哪个库,所以我将使用SQLite作为我头部示例的顶部。采用分层的方法,我会做这样的事情:

A)高级别对象(订单,客户,供应商......)

B)基类(录音)

C)的SQLite

因此,基类是为了直接调用SQLite而编写的,其他类就像普通的Objective-C类一样工作。

这被并列于:

1)高级对象(订单,客户,供应商...)

2)基类(记录)

3)SQLite的包装(Objective- C)

4)SQLite的

创建同一个应用程序,但有额外的工作创建,维护和调试3级很少以显示它。

在第一个版本中,B层包装SQLite,所以没有超过它直接调用SQLite,它并没有尝试提供所有的SQLite功能。它只是提供A层需要的功能,并使用SQLite来实现所需的功能。它'包装'SQLite,但以更具体应用的方式。相同的Record类可以稍后在另一个应用程序中重用并扩展以满足当时这两个应用程序的需求。