37

Objective C、特に Cocoa Touch のコードのにおいについて、皆さんの意見をお聞きしたいと思います。私はかなり複雑なゲームに取り組んでおり、Great December Refactoring を開始しようとしています。

私のクラスのかなりの数、特にモデルは、内部のビジネス ロジックを処理するメソッドでいっぱいです。大規模なヘッダー ファイルとの戦いで、これらをプライベート カテゴリに非表示にします。これらのプライベート カテゴリには多数の宣言が含まれており、これは私を不安にさせます...まるで、Objective-C がこれらすべてのメソッドについて罪悪感を感じさせようとしているかのようです。

リファクタリングをすればするほど (良いことです!)、この重複をすべて維持する必要があります (あまり良くありません)。気分が悪いだけです。

Ruby のような言語では、コミュニティは非常に短く、明確で、美しいメソッドに重点を置いています。私の質問は、Objective C (具体的には Cocoa Touch) の場合、メソッドの長さ、コントローラーの大きさ、およびクラスごとのメソッドの数がプロジェクトで一般的になっていることがわかりますか? Objective C の短いメソッドで構成されたクラスの特に素晴らしい、美しい例はありますか? それとも、それは単に言語の文化の重要な部分ではないのでしょうか?

開示: 私は現在、私の悲しみを説明するはずの "The Little Schemer" を読んでいます。re: Objective C.

4

3 に答える 3

15

美しさは主観です。私にとって、Objective-C クラスは、読みやすく (何をするべきかを知っている)、保守しやすい (どの部分が何をするのかを理解できる) 場合に美しいと言えます。また、なじみのないイディオムによってコードを読むことから放り出されるのも好きではありません。本を読んでいるときに何かを読んで、没入感から抜け出し、読んでいることを思い出させるようなものです。

おそらく、相互に排他的なさまざまなアドバイスを得るでしょうが、ここに私の考えがあります。

  • プライベート メソッドがプライベート カテゴリにあることに問題はありません。それがその目的です。宣言がファイルを詰まらせたくない場合は、IDE でコードの折りたたみを使用するか、拡張機能を別のファイルのカテゴリとして使用してください。
  • 関連するメソッドをグループ化し、#pragma markステートメントでマークします
  • どのようなコード レイアウトを使用する場合でも、一貫性は重要です。数分かけて、独自のガイドラインを書いてください (ここにのものがあります)。
  • コントローラーはデリゲートである必要はなく、データソースは常にこれらの他のクラスを持つことができます。
  • メソッドとプロパティにはわかりやすい名前を使用してください。はい、それらを文書化することはできますが、Xcode がコード補完を適用するときに文書を表示することはできません。また、コード自体が変更されている間にコード コメントが更新されないと、コード コメントが古くなります。
  • 賢いコードを書こうとしないでください。一連のメソッド呼び出しを 1 行にまとめた方がよいと考えるかもしれませんが、コンパイラは思ったよりも最適化に優れています。一時変数を使用して値を保持することは問題ありません (ほとんどの場合、これらはポインタにすぎないため、比較的小さいものです)。読みやすさが向上する場合。人間が読めるコードを書く
  • DRY は、他の言語と同様に Objective-C にも適用されます。コードをより多くのメソッドにリファクタリングすることについて心配する必要はありません。メソッドが有用である限り、メソッドがたくさんあっても問題はありません。
于 2010-12-09T11:47:47.463 に答える
7

クラスやメソッドを実装する前であっても、私が最初に行うことは、「これを外部からどのように使用したいか?」と尋ねることです。

クラスとメソッドの内部を最初に書くことから始めることは決してありません。エレガントなパブリック API から始めることで、内部は無料でエレガントになる傾向があります。そうでない場合、醜さは少なくとも 1 つのメソッドまたはクラスに含まれており、コードの残りの部分を臭いで汚染することはできません。 .

世の中には多くのデザイン パターンがありますが、20 年間のコーディングの経験から、時の試練に耐える唯一のパターンはKISSであることがわかりました。シンプルに保ちましょう。

言語や環境に関係なく、いくつかの一般的な経験則があります。

  • 読んだり聞いたりしたアドバイスについては、直感に従ってください。
  • 早期救済!
    • 必要に応じて、入力を早期に検証し、迅速に救済してください! 行うクリーンアップが少なくなります。
  • 使用しないものをコードに追加しないでください。
    • 「逆」のオプションは、将来的には便利なもののように感じるかもしれません。
    • その場合は、途中で追加してください。必要のない複雑さを追加して時間を無駄にしないでください。
  • メソッド名は、どのように行われるかではなく、何が行われるかを説明する必要があります。
    • メソッドは、結果が同じである限り、名前を変更せずに実装を変更できるようにする必要があります。
    • 名前からメソッドの機能が理解できない場合は、名前を変更してください。
    • how 部分が非常に複雑な場合は、コメントを使用して実装を説明します。
  • シングルトンを恐れるな!
    • アプリのデータ モデルが 1 つしかない場合、それはシングルトンです。
    • あちこちで単一の変数を渡すことは、それがシングルトンではなく別のものであるふりをして、ボーナスとして複雑さを加えているだけです。
  • 最初から失敗を想定してください。
    • doFoo:error最初からではなく、常に for を使用しdoFoo:ます。
    • NSError最初から、エンド ユーザーが読みやすいローカライズされた説明を使用して、適切なインスタンスを作成します。
    • エラー処理/メッセージを大規模な既存のアプリに後付けするのは大きな苦痛です。
    • また、ユーザーと IO が関係している場合は、常にエラーが発生します。
  • Cocoa/Objective-C はObject* 指向であり、**クラス指向ではなく、OOP であると主張する人気のある子供たちのほとんどです。
    • プロパティのみを持つ愚かな値クラスを導入しないでください。実際の作業を実行するメソッドのないクラスは、構造体である可能性があります。
    • オブジェクトを知的にしましょう! 必要なのはメソッド onだけなのに、まったく新しいFooParserクラスを追加する必要はありません。fooFromString:Foo
  • Cocoa では、自分が何をするかよりも、何ができるかが常に重要です。
    • ターゲット/アクションが実行できる場合は、プロトコルを導入しないでください。
    • インスタンスがプロトコルに準拠していること、それがクラスの一種であること、コンパイラ次第であることを確認しないでください。
于 2010-12-12T11:44:05.047 に答える
2

私の2セント:

  1. プロパティは通常、古いスタイルの getter+setter よりも優れています。@dynamic プロパティを使用している場合でも、@property で宣言すると、より有益で短くなります。
  2. 私は個人的に、クラスの「プライベート」メソッドをシミュレートしません。はい、.m(m) ファイルのどこかにカテゴリを記述できますが、Obj-C にはプライベート メソッドを宣言する純粋な方法がないため、なぜそれを発明する必要があるのでしょうか? とにかく、本当にそのようなものが必要な場合でも、宣言の重複を避けるために、別の「MyClassPrivate.h」をカテゴリで宣言し、.m(m) ファイルに含めます。
  3. バインディング。ほとんどの Controller <-> UI リレーションのバインド、トランスフォーマー、フォーマッターの使用、コントロール値を手動で読み書きするメソッドを記述しないでください。コードは MFC 時代のもののように見えます。
  4. C++の場合、多くのコードは C++ で記述した方が見栄えが良く、短くなります。コンパイラは C++ クラスを理解するので、特に低レベルのコードで作業する場合は、リファクタリングに適しています。
  5. 私は通常、大きなコントローラーを分割します。500 行を超えるコードは、リファクタリングの対象として適しています。たとえば、アプリの一部のバージョンは画像のインポート/エクスポート オプションで拡張されているため、ドキュメント ウィンドウ コントローラーがあります。コントローラーは最大 1.000 行まで成長し、1/2 は「イメージのもの」です。これは、ImageStuffController を作成し、NIB でインスタンス化し、すべてのイメージ関連コードをそこに配置するための「トリガー」です。

上記のすべてにより、コードの保守が容易になります。コントローラーとクラスを分割して小さな結果を維持するために膨大な数のファイルを作成する大規模なプロジェクトの場合、通常、いくつかのコードをフレームワークに抽出しようとします。たとえば、アプリの大部分が外部 Web サービスと通信している場合、通常、メイン アプリから MyWebServices.framework を直接抽出する方法があります。

于 2010-12-09T11:24:41.793 に答える