0

私は、iPhone と iPad の 2 つの根本的に異なるビューを持つ長期保守コード ベースを継承しました。これにより、1,000 行以上のコードに膨れ上がった 1 つの大きな UIViewController クラスが作成されました。これは、ISIPAD ステートメント、プライベート変数、プロパティ、iBOutlets/Actions のマッシュアップであり、たとえば、ある実装では UITableView を使用し、別の実装ではまったく異なるものを使用します。

さらに悪いことに、現在のソフトウェア パターンはサブクラス化に依存しています。

現在、次のようになっています。

ParentVC (both iphone/ipad God class also has xib(xib~ipad) + iboutlets/actions)
      |         |            |
    ChildA    ChildB       ChildC

私が最初に考えたのは、ParentVC を iPhone/iPad 固有のクラスに分割することでした。

               ParentVCBase
         |                     |
     ParentVC_iPad(xib~ipad)  ParentVC_iPhone(xib)
         |                       |
   ChildA/B/C_iPad         ChildA/B/C_iPhone

ファクトリ呼び出しを介して正しい Child サブクラスを吐き出します。

私が遭遇した問題は、各子がいくつかの ParentVC メソッド呼び出しをオーバーライドし、デバイス固有ではない独自の機能固有のメソッドを実装することです (元のサブクラス化の主な目的はビュー レイアウトを共有することでした)。このデザイン パターンは、ChildA_iPhone と ChildB_iPad のコードを複製した場合にのみ機能します。あるアンチパターンを別のアンチパターンと交換したので、それは避けたいと思います。

私はここで少し途方に暮れています。実行時に Child クラス (objc/runtime.h) を作成し、必要な Child メソッドを参照 Child クラスからスウィズルすることをほぼ検討しましたが、それは現在よりも混乱しているようには見えません。簡単にクリーンアップするために、ParentVC ヘッダー (IBOUTlets、プロパティなどの大きなリストを含む) を保持し、デバイス固有のメソッドをカテゴリに配置して、実際のリファクタリングが必要になる日まで少なくとも機能を分離することも検討しました。

ある時点でこれに対処しなければならなかったiOSアーキテクトがいるかどうか、または彼らがどのように対処するかは興味深い.

4

1 に答える 1

0

これは、オブジェクト指向の設計に関する質問であるほど、iOS 固有の質問ではありません。

コードの重複は絶対に避けたいものです。重複は多くの悪の源です。

一般に、クラスを設計する際に継承の制限によって制限されないようにする必要があります。あなたが目指したいのはクラス構成です。

したがって、ブリッジ パターンを使用して、次のようなデザインに移行できます。

  ParentVC           --->             ImplementationA
   |    |                               |            |
ChildA ChildB                 Implementation_iPhone Implementation_iPad

ここで、ParentVC は上記と同じクラス階層を持ちますが、実装には別のクラス階層、ImplementationA を使用します。そのクラス階層は、iPhone と iPad のバージョンに分類されます。クラス ImplementationA は、ParentVC にあった実装の中身を保持します。

継承は設計パターンですが、数あるパターンの 1 つにすぎません。その 1 つのパターンだけを使用することに固執すると、悪いデザインを作成することに行き詰まります。システムを適切にモデル化するには、パターンを組み合わせる必要があります。

もちろん、これらの変更を行っているときに何かを壊さないように、できる限り単体テストを使用してください。

于 2012-08-01T04:13:27.897 に答える