5

問題

Userオブジェクトとオブジェクトを持つアプリケーションがありStudentます。一部のユーザーは学生です。すべての生徒がユーザーです。データベース (django-ORM ベース) では、これはStudentテーブルへの外部キーを持つテーブルとして表されUserます。

REST API と、この API をモデル化する iOS アプリのオブジェクト階層を作成しようとしています。これをモデル化する方法を決定するのに問題があります。

現在のソリューション

私が思いついた最高のものは次のとおりです。iOSにモデルUserを持ち、iOSにStudentモデルを継承しUser、それをより多くのプロパティで拡張します。次に、サーバーから JSON 応答を受信し、辞書に応じてa またはモデルを作成するメソッドを用意します。UserStudent

最後に、サーバーは常に最も具体的なタイプを提供する必要があります。つまり、サーバーにログインすると、サーバーは私が学生か通常のユーザーかを判断し、適切な辞書を返します。

これが最善の方法ですか?

これは少し複雑に聞こえます。しかし、データベースのレイアウト方法を変更するなど、モデル化について私が考えた他の方法では、データベースがすべての制約を認識していない設計が得られます。たとえば、Studentオブジェクトは他のオブジェクトを所有できます (例: homework_paper)。Userオブジェクトではなく、オブジェクトへの外部キーでこれをモデル化できます。これは、単にユーザーの拡張であるStudentと言えます。しかし、データベースは、 a が学生によって所有されなければStudentならないという事実を強制しません。homework_paper

私が見逃しているこの問題を解決するより良い方法はありますか?

4

1 に答える 1

2

UI レイヤーのクラスがドメイン クラスと 1 対 1 で一致する必要があるということは何もありません。ドメイン クラスがデータベース テーブルに正確に従う必要がないのと同じように。

UI レイヤーのクラスは、UI 表現を別のクラスのセットと考えることができます。UI を機能させるために必要なクラス、またはドメイン モデルやデータベース設計のビジネス ルールを損なうことなくフレームワークを有利に使用するために必要なクラス。

ユーザー UI クラスは、ユーザー ドメイン クラスと学生ドメイン クラスの両方をラップするクラスである可能性があります。User ドメイン クラスと Student ドメイン クラスの両方の知識が必要です。User または Student のいずれかをインスタンス化するのは、このラッパー クラス次第です。

もう 1 つのアプローチは、ユーザーと生徒の関係を「is a」ではなく「has a」の関係としてモデル化することです。結局のところ、ユーザーが学生だけでなく教師でもある場合、あなたは何をするつもりですか。たとえば、教師が自分が教えているコース以外のコースに登録する場合などです。通常、これらの種類の関係は、「である」関係としてよりもロールを使用してモデル化する方が適切です。役割の扱いについて詳しくは、Martin Fowler を参照してください。

いずれにせよ、ユーザー UI クラスは、REST 実装での表現の基礎となり、ユーザーまたは学生、または役割ベースのアプローチでは、それに関連する学生のもの:

{
  "user": "/users/1234",
  "name": "Some non student's name",
  "stats": {
    ...
  }
}, 
{
  "user": "/users/4567",
  "name": "Some Student's name",
  "stats": {
    ...
  }
  "papers": [
    { "paperid": "/users/papers/111"
      ...
    },
    { "paperid": "/users/papers/222"
      ...
    },
    { "paperid": "/users/papers/333"
      ...
    }
  ]
}

コメントに応じて編集

UI でユーザーと学生を URI レベルで区別する必要がない限り、サーバーは何らかのレベルでそれを決定する必要があります。私は反対をお勧めします。使いにくいUIになります。ユーザーは実装の詳細に興味がなく、それらに直面したくありません。

しかし、いいえ、ifは必要ありません。

ポリモーフィズムを有利に使用します。

サーバーは、id で取得したユーザーのデータ アクセス フレームワークから学生インスタンスを受け取ることで、ポリモーフィズムを有効に活用できます。結局のところ、学生はいつでもユーザーとして参照できます。したがって、サーバーは、データ アクセス フレームワークから取得したユーザー参照が学生である可能性があるという事実を単純に無視できます。サーバーが実際に特定の学生のものを実行/追加する必要がある場合は、派生クラスで実行する必要があります。

これには if ステートメントをどこでも使用する必要はありません。UIクラスでさえありません。UI は、受け取る User 参照が Student である可能性があることを認識し、それに応じて動作する必要があるだけです。できればif User is Student(UI の方法をクラス階層に深く結びつけることになります) ではなくif IUser implements IStudent、User 参照に Student インターフェイスも実装しているかどうかを尋ね、その ISt​​udent インターフェイス参照を取得して使用します。

于 2012-11-02T17:26:49.633 に答える