1

私は独学のプログラマーであり、他の多くの初心者と同じように、かつては古典的な「フォーム間でデータを渡す」問題に苦労していました。1年ほど前にJavaで最初のチャットアプリケーションを構築していたときに、この問題に再び遭遇しました。実行中のGUIへの参照を別のクラスのコンストラクターに渡して、GUIを直接操作できるようにすることで解決しました。例えば:

class GUI {
    Writer w;
    void initGUI() {
        w = new Writer(this);
    }
}

class Writer {
    GUI ui;
    public Writer(GUI ui) {
        this.ui = ui;
        ui.textBox.write("Yo");
        // now, instead of the "this" keyword, I can say "ui.w" or "ui.w.ui.w.ui.w..."
    }
}

これがデータを「上流」に転送する最も効率的な方法の1つであると確信していますが、同じ問題を抱えている人のためにフォーラムでこれを提案したことに対して、私は悲しみ(そしていくつかの賞賛)を与えられました。では、大規模なアプリケーションでこれを行うと、どのような混乱が生じる可能性がありますか?これを使用するアプリケーションを見ると、非常に実用的で効率的ですが、少し有機的すぎて(もしそうなら)複雑すぎます(特に、異なる時間にGUIにアクセスするスレッドがある場合など)。

これを行うためのより良い方法はありますか?Qtを使用している間、必然的に別のアプローチを取りましたが、シグナル、スロット、およびスレッドを使用するため、より複雑でした。私を正しい方向に向けてください。ありがとう。

4

3 に答える 3

4

このアプローチの主な問題は結合です。Writerクラスは、汎用的で再利用可能なWriterクラスではなく、その役割を果たし、必要に応じて、その機能に関するイベントを送信できるため、この特定のGUIと緊密に結合されています。

すべてのSwingコンポーネントと同様に、リスナーを受け入れる場合は、ライターをいくつかの異なるGUIで再利用するか、たとえばテキストフィールドの代わりにテキスト領域を更新することを選択できます。

別の解決策は、プッシュではなくプルを使用することです。ライターにGUIを更新させる代わりに、ライターの状態を照会するために、ライターのGUI呼び出しメソッドを使用することができます。常に可能であるとは限りませんが、多くの場合可能です。

于 2012-12-09T19:17:20.177 に答える
1

実行中のGUIへの参照を別のクラスのコンストラクターに渡して、GUIを直接操作できるようにすることで解決しました。

ビジネスロジックをプレゼンテーション層から切り離したいと考えています。GUIとは関係なく、ビジネスロジックを分離してテストできるようにする必要があります。バックエンドを変更せずに、フロントエンドのGUIを変更できるようにする必要があります。これは、関心の分離として知られています。

これを実現するのに役立つ多くのデザインパターンがあります。

その1つがModelViewController(MVC)です。

GUIを直接操作する代わりに、モデルを直接操作します。

于 2012-12-09T19:30:46.877 に答える
0

はい、Javaは間違いなくオブジェクトとの参照渡しです。

しかし、あなたがしていることは、あなたWriterがあなたが石で書かれていると仮定しているということです。GUIつまり、それは常にと呼ばれるプロパティを持っているということtextBoxです。

物事の見た目だけで、Writerのプロパティにアクセスして操作する責任を負わないようにする必要がありますGUI。の内容を変更する場合は、クラスGUIも再コーディングする必要があります。Writer

Writerにメッセージを送信するように再コーディングすることもできます。これはGUI、その責任はGUI、書き込み方法ではなく、何を書き込むかを指示することだけであるためです。GUI次に、そのメッセージを処理するのはに任せます。

class GUI
{
     Writer w;
     void initGUI()
     {
        w = new Writer(this); 
     }

     void ReceiveMessage(string message)
     {
         this.textBox.text = message;
     }
}

あなたのWriterクラス:

class Writer
{
    GUI ui;

    public Write(GUI ui)
    {
         this.ui = ui;
         // Don't send the message in the constructor.
    }

    // The program calls this function with whatever text the user enters.
    public void SendMessage(string message)
    {
        ui.ReceiveMessage(message);
        // Writer no longer depends on ui to have a textbox Element.
    }
}

上記のコードは、インターフェースを使用して改善できます。このようにして、メッセージの受信方法を知る必要があるライターに何でも渡すことができます。

interface IMessageReceiver
{
    void ReceiveMessage(string message);
}

これで、GUIIMessageReceiverになります。

class GUI implements IMessageReceiver
{
     Writer w;
     void initGUI()
     {
        w = new Writer(this); 
     }

     public void ReceiveMessage(string message)
     {
         this.textBox.text = message;
     }
}

Writer今のクラス:

class Writer
{
    IMessageReceiver receiver;

    public Write(MessageReceiver receiver)
    {
         this.receiver = receiver;
         // Don't send the message in the constructor.
    }

    // The program calls this function with whatever text the user enters.
    public void SendMessage(string message)
    {
        receiver.ReceiveMessage(message);

    }
}

ここでの違いは、それWriterがであるかどうかはもう気にしないということGUIです。IMessageReceiverメッセージの受信方法を知っているオブジェクトであれば、どのオブジェクトでもかまいません。

インターフェイスに慣れていない場合は、インターフェイスを読んだり調べたりしてください。それらは非常に便利ですが、そうでない場合は不可欠です!

于 2012-12-09T19:39:06.993 に答える