1

私が受講しているプログラミングコースでは、プライベートメンバーのみを使用することが許可されており、このようなもので大丈夫かどうか疑問に思いました。

public class View {
    private Model object_;
    public View(Model object) {
       object_ = object;
       //blah blah blah
    }
//blah blah blah
}

public class Controller {
    private Model object_;
    public Controller(Model object) {
       object_ = object;
       //blah blah blah
    }
//blah blah blah
}

public class MainClass {
    public static void main(String [ ] args) {
        Model m = new Model();
        Controller c = new Controller(m);
        View v = new View(m);
        //blah blah blah
    }
}

ViewクラスとControllerクラスはどちらも、プライベートフィールドと同じモデルのインスタンスを保持します。これは受け入れられますか?プライベートフィールドの概念に違反しているようです。教授に聞いてみたところ、大丈夫だと言われましたが、彼が私の質問を理解したのか、それとも彼の答えを理解したのかわかりません:)

4

7 に答える 7

2

タイトルの質問について:はい、大丈夫です。兄弟が親への参照を共有するツリーを考えてみてください。この状況は非常に一般的です。

于 2009-11-03T23:44:50.797 に答える
1

この記事を見ると、理想的にはコントローラーがモデルとビューの間にあることがわかります。だから私はおそらくあなたの依存関係をいくらか再編成するでしょう(これについてはいくつかの意見の相違があります-以下を参照してください)

しかし、(ドメインに関係なく)あなたの質問に対する答えは、これらのプライベート参照を共有できるということです。理想的には、それらはインターフェースへの参照である必要があり、依存クラスを変更せずに実装を変更できます。したがって、(たとえば)Modelインターフェイスと実装ModelImplがあり、共有参照のタイプはModelです。その後、コードの大部分に影響を与えることなく、後日、さまざまな実装を置き換えることができます。

于 2009-11-03T23:41:46.447 に答える
1

簡単に言えば、それは問題ないということです。

より長い答え(MVCはそれを行う例であり、質問の核心ではないように思われるため、MVCについて少し忘れる)は、可変性について考える必要があるということです。オブジェクトが変更可能でない場合(オブジェクトのどのフィールドも変更できない場合)、共有は非常に良いことであり、メモリフットプリントを削減し、実際の欠点はありません。

ただし、オブジェクトが変更可能である場合は、オブジェクトの状態を変更すると、それを参照するオブジェクトにどのように影響するかを理解する必要があります。MVCでは、モデルが変更され、それに基づいて最終的にビューが調整されるのが非常に一般的であるため、それを設計に組み込むことになりますが、次の場合を考慮してください。

  private Collection myCollection; 

  public void setMyCollection(Collection someCollection) { 
       myCollection = someCollection; 
  }

このようなコードは、呼び出し元が後で変更される可変コレクションを渡さないことを非常に確信している必要があります。そうでない場合は、それを許可する必要があります。上記の場合の問題を回避する一般的な方法は、コピーを作成することです(myCollection = new ArrayList(someCollection);

要約すると、これは問題ない一般的な方法ですが、オブジェクトが変更可能である場合は、設計への影響を検討する必要があります。

于 2009-11-03T23:52:54.567 に答える
1

簡単な答え:同じものを参照するプライベートメンバー変数を持つ2つの異なるクラスに問題はありません。それはかなり一般的です。

長い答え:私の推測では、あなたの教授がここで話していた
private Model object_のは、オブジェクト参照変数(プリミティブではない)です。したがって、ControllerとViewのコンストラクターに渡すとき は、のコピーを渡す代わりに、object_の同じインスタンスに「リンク」を渡します。
object_ object_

それらをControllerandViewにプライベートとして保存することを選択するかどうかは、まったく別の決定です。私は、非プライベートメンバー変数(そこにある)の使用を禁止する大学のプログラミングコースに精通しています。彼らは、カプセル化(後で)などのオブジェクト指向の概念を導入したいと考えています。次に、プライベートメンバー変数のパブリックアクセサーとミューテーターを作成するように指示します。保護されたメンバー変数とパブリックメンバー変数は、正当な理由がある場合にのみ使用する必要があるため、これは一般的に最初から適切な原則です。

そうです、これらは正しいJavaですが、これが実際にコードで何をしたいかは別の問題です(Calebの回答を参照)。

于 2009-11-03T23:54:49.143 に答える
1

これは受け入れられますか?

はい、そうです。

プライベートフィールドの概念に違反しているようです

そうではありません。プライベートであるため、コントローラーはビューからインスタンスを変更できません。

ビュー内のモデルを変更しようとする次のコード行について考えてみます。

public class Controller {
    private Model object_;
    public Controller(Model object) {
        object_ = object;
        this.object_.view.object_ = new Model(); // doesn't work.
        // or view.object_ = ....            
       //blah blah blah
    }
    //blah blah blah
}

これは機能しません。1つはモデルにビューへの参照がないためです。2つは、モデルにビューが表示されている場合は、ビューが表示されないため、ビューをcontroller変更できませんmodel

同じオブジェクトを共有することは、状況によっては望ましくない場合があります。たとえば、特定のオブジェクトの状態に依存していて、その状態が他のオブジェクトによって変更されている場合、コードが失敗する可能性があります。防御的コピーを参照してください。そのため、不変オブジェクトを使用し、そのオブジェクトへのアクセスを制限することをお勧めします。

しかし、特にMVCデザインパターンでは、まさに必要なものであるオブジェクトを共有するか、少なくともそのオブジェクトの状態を共有します。MVCで必要なのはView、状態Controllerを認識することModelです。同じオブジェクトを表示しても、プライベート性が低下することはありません(各オブジェクトが同じものを表示していることを認識していないという意味で)。これにより、低結合が可能になります。

オブジェクトのプライバシーを確​​実に台無しにするものは、次のように非プライベートとしてその属性を持ちます。

class View {
   public Model m; 
}
class Controller {
    public Model m;  
}
....
public static void main( String ... args ) { 
     Model m = ... 
     View v = new View();
     Controller c = new Controller();
     v.m = m;
     c.m = m;
}

ワイルドな変更の発生を防ぐアクセス制御がないためです。

于 2009-11-04T00:19:57.497 に答える
0

私の知る限り、オブジェクトを複数のクラスでプライベートに保持できるという、厳格で迅速な「プライベートフィールドの法則」はありません。不変の参照クラスのようなものの場合、複数のクラスインスタンスが不変の参照クラスを受け取り、それをプライベート属性として保持できることは理にかなっています。

あなたの例では、Carlは正しいです-ビューとコントローラーは通常、それらへの参照を保持するのではなく、何らかのメソッドのパラメーターとしてモデルを取得する必要があります。したがって、コードは次のようになります。

public Response handleRequest(Request request) {
    Controller c = new Controller();
    Model m = c.processRequest(request);
    View v = new View();
    Response response = v.createResponse(model);
    return response;
}
于 2009-11-03T23:41:35.073 に答える
0

はい、これは許容されます。必要に応じて、getter / setterメソッドを介してこれらのフィールドへのアクセスを制御することにより、カプセル化を強制するためにプライベートフィールドを使用する必要があります。これらのフィールドがパブリックまたはパッケージである場合、外部クラスはクラスの実装に依存し始める可能性があり、リファクタリングメソッドなどの点で拘束されます。他のクラスがアクセスできるはずのフィールドへのアクセスを許可すると、プライバシーリークが発生する可能性があります。

公開されているモデルの場合。

クラスmessUp{

モデルaModel=object_; aModel.doWhatTheHellIWantToYourModel();

}

これにより、システムの状態が完全に無効になる可能性があります。

于 2009-11-03T23:43:00.283 に答える