Objective-Cでは、外部に公開するメソッドをわざわざヘッダファイル側に宣言する必要があるため、非常に面倒だと思われていますが、個人的な経験上では、それほど手間にはならないと感じています。
そもそも公開メソッドがそれほど多くなることはないですし、むしろプロパティやプライベートメソッドのほうが頻繁に定義されるくらいです。
その点、Objective-Cはプライベートメソッドの実装が他の言語よりも簡単に行えるという特徴があります。private/protectedなどという修飾子を用いる必要もありません。
// Objective-C
- (void)privateMethod {}
// Java
private void privateMethod() {}
// Swift
private func privateMethod() -> Void {}
Objective-C側のコードではprivateというアクセス制御修飾子が使われていない点に注目してください。
Objective-Cでは基本的に、ヘッダーファイル側に宣言されたメソッドしか外部から呼び出せません。逆にヘッダファイルに書かれていないメソッドは、暗黙的にプライベート扱いになるため、わざわざprivate修飾子による明示を行う必要もありません。
実際、ヘッダーで宣言されていないメソッドを外部から呼び出そうとすると、コンパイルエラーが発生します。無理やり呼び出そうと思えば呼び出すことも出来ますが、それなりの手間がかかるため、Objective-Cでは事実上、ヘッダファイルで宣言されていないメソッドはプライベート扱いされていると見なすことができます。
なんというか、えらく泥臭いルールですが、とてもおもしろい発想だと思います。
デメリット
privateという識別子が使えなくなるため、コードの可読性が下がってしまうという問題はありますが、その点は命名規則で解決出来ます。
実際、Objective-Cの世界では、メソッド名の先頭にアンダースコアを付与することで、プライベートメソッドであることを明示する慣習があります。
// アンダースコアで始まるメソッドは暗黙的にプライベート扱い
-(void)_privateMethod {}
-(void)publicMethod {
// 呼び出し側でもプライベートであることが一目瞭然
[self _privateMethod];
}
呼び出し側でもプライベートメソッドを呼び出していることが明確になるため、広い範囲でコードの可読性が高まるというメリットもあります。
またもう一つのデメリットとして、ObjCにはprivateキーワードだけでなくoverrideキーワードも存在しないという問題があります。これによって意図せぬオーバーライドが発生してしまう危険性が生まれます。この問題については、メソッド名の命名をしっかりと行うことで、ある程度の対処が可能です。また継承を多様するクラス設計を極力避けるようにし、委譲によるクラス設計やカプセル化を重視することもオススメです。プレフィックスの活用(xx_methodName
)も考えられます。
プロパティ/インスタンス変数でも有効
最近のObjective-Cでは、プロパティ/インスタンス変数を実装ファイル側で宣言することも出来ますので、ヘッダーファイル側の情報を更に削ることが可能です。
以下の宣言(privateProperty
, _privateInstanceVar
)はいずれもヘッダー側で行う必要がありません。
/* Hoge.m */
@interface Hoge ()
@property id privateProperty; // 非公開プロパティ
@end
@implementation Hoge {
id _privateInstanceVar; // 非公開インスタンス変数
}
-(void)test {
// 内部からのみアクセス出来る
NSLog(@"%@", _publicInstanceVar);
NSLog(@"%@", self.privateProperty);
}
@end
ミニマルな言語思想
JavaやSwiftの場合は、privateキーワードの付いた情報もユーザの目に触れてしまい、また様々なキーワード(public/private/protected)やアノテーションを使い分ける必要があったりと、非常に繁雑で面倒な所がありますが、Objective-Cでは、ヘッダーファイルという非常に原始的な仕組みによって同等のことをよりシンプルな形で体現している点が実に斬新です。
C言語やObjective-Cの泥臭さにはミニマリズム的なものが感じられて、とても面白いと感じます。
ヘッダファイルの存在意義について思う所
公開インターフェイスがヘッダファイル側に集約されているという事実は、ドキュメント的な観点で見ても、優れていると感じます。ソースコードはプログラム仕様におけるある種の仕様書みたいな物ですので、ヘッダファイルによって公開インターフェースを明文化することは、とても有益なことなのです。ヘッダーファイルはドキュメントにおける「目次」や「索引」「チートシート」、建築における「青写真」のような存在だと言えます。それをpublicやprivateという仕組みで包括し、ヘッダの役割を擬似的なヘッダーファイル・ジェネレータやJavadoc等の外部ツールに委ねたJava言語やSwift言語の決断には相当大きな覚悟があったのではないかと思い做します。