10

私は独学でプログラミングを学んでおり、.NET プログラミングの正式なトレーニングは受けていません。

少し前に、センサーを制御する GUI プログラムを開発するために C# を開始し、プロジェクトが開花しました。フォーム内のコード、特に UI コードをどのように整理するのが最善かを考えていました。

現在、私のフォームは混乱しているか、少なくとも私には混乱しているように見えます。

  • すべてのパラメーターを初期化し、イベントを作成するコンストラクターがあります。
  • 私は巨大な State プロパティを持っています。これは、ユーザーが State 列挙型によって制御されるアプリケーション (つまり、切断、接続、セットアップ、スキャン) を進めるにつれて、すべてのフォーム コントロールの Enabled 状態を更新します。
  • プロパティを介してアクセスする 3 ~ 10 個のプライベート変数があり、そのうちのいくつかはフォーム要素の値を変更する際に副作用があります。
  • 他の UI 要素に依存する UI 要素を処理する「UpdateXXX」関数がたくさんあります。つまり、センサーが変更された場合は、ボー レートのドロップダウン リストを変更します。それらは地域に分かれています
  • これらの更新関数を呼び出すイベントがたくさんあります
  • すべてのスキャンと分析を行うバックグラウンド ワーカーがいます。

私の問題は、これが混乱しているように見え、特に State プロパティが維持できなくなっていることです。また、私のアプリケーション ロジック コードと UI コードは同じファイルにあり、ある程度混ざり合っているため、間違っているように見え、必要なものを見つけるために何度もスクロールする必要があります。

.net フォームをどのように構成していますか?

ありがとう

4

8 に答える 8

5

アプリケーションでロジックを分離するのに役立つパターンがいくつかあります。これにより、コードがよりクリーンで保守しやすくなります。MVP パターンは、開始するのに適したパターンです。これは、責任の 3 つの領域、つまり MVP M = モデル、V = ビュー、P = プレゼンターの定義に基づいています。インターフェイスの使用に慣れている場合は問題ありませんが、それ以外の場合は、開始するのに適しています (基本的な OO の原則を確認してください: カプセル化、抽象化、ポリモーフィズム)。MVP の基本原則は、プレゼンターにアプリケーション ロジックを配置することです。プレゼンターはインターフェイスを介してビュー (フォーム) と対話し、ビューはユーザーがプレゼンターと対話するときにプレゼンターにコールバックします (私はこれにもインターフェイスを使用します)。モデルは、ビジネス ロジックとエンティティ関係を実装するソリューションのドメイン オブジェクト階層です。

ほとんどの UI パターン (MVP、MCV など) は、同じことを行おうとしています。以下は簡単な例です。

//ビューインターフェース

interface IUserDetailsView
{

      string Username{set;get;}
      string FirstName{get;set;}
      string LastName{get;set;}
      UserDetailsPresenter Presenter{get;set;}
      void DisplayMessage(string message);


}

//ビューの実装 //テキスト ボックス、ラベル、コンボなどを持つ標準の Windows フォーム。

class UserDetailsView : Form, IUserDetails
{

      public string Username{set{txtUserName.text = value;}get{return txtUserName.text;}}
      public string FirstName{set{txtFirstName.text = value;}get{return txtFirstName.text;}}
      public string LastName{set{txtLastName.text = value;}get{return txtLastName.text;}}

      Public UserDetailsPresenter Presenter{get;set;}

      public void DisplayMaessage(string message)
      {
         MessageBox.Show(message);
      }

      private void saveButton_Click(object sender, EventArgs e)
      {
         Presenter.SaveUserDetails();

      }
}

//プレゼンテーション ロジック

クラス プレゼンター UserDetailsPresenter {

  //Constructor
  public userDetailsPresenter(IUserDetailsView view)
  {
    //Hold a reference to the view interface and set the view's presnter
     _view = view;
     _view.Presenter = this;
  }

  private IUserDetailsView _view;

  DisplayUser(string userName)
  {
     //Get the user from some service ...
     UserDetails details = service.GetUser(userName);

     //Display the data vioa the interface
     _view.UserName = details.UserName;
     _view.FirstName = details.FirstName;
     _view.LastName = details.LastName;

  }

  public void SaveUserDetails()
  {

       //Get the user dryaiols from the view (i.e. the screen
       UserDetails details = new UserDetails();

       details.UserName = _view.UserName;
       details.FirstName = _view.FirstName;
       details.LastName = _view.LastName;

       //Apply some business logic here (via the model)
       if(!details.IsValidUserDetails())
       {
          _view.DisplayMessage("Some detail outlining the issues");
         return;
       }

       //Call out to some service to save the data
       service.UpdateUser(details);

  }

}

//最後に、モデル

public class UserDetails
{

   public UserName {get;set;}
   public FirstName{get;set;}
   public LastName{get;set;}

   public bool IsValidUserDetails()
   {
       if(LastName == "Smith")
       {
          //We do not allow smiths, remember what happened last time ... or whatever
          return false;
       }

       return true;
   }

}

うまくいけば、これは責任がどのように分離されているかを説明しています。フォームには、表示/書式設定など以外のロジックはありません。テスト用にスタブ化することもできます。プレゼンターはビューとモデルの間のメディエーターであり、サービスを呼び出します。モデルはビジネス ロジックを実装します。すでに示唆されているように、このパターンにはバリエーションがあり、コードを少しスリムで柔軟にすることができますが、基本原則の概要は次のとおりです。これが役立つことを願っています。

:-)

于 2010-06-16T10:47:39.250 に答える
2

複雑なフォームでは、通常、コードを別々のファイルに分割します。これは、「部分クラス」を使用して行うことができます。各ソース コード ファイルは、フォームに基づいて名前が付けられます。たとえば、MainForm.cs、MainForm.State.cs、MainForm.Update.cs、MainForm.Menu.cs などです。複雑なフォームが多数ある場合は、それぞれにサブフォルダーを作成します。ここでの 1 つのヒントは、MainForm.Wip.cs フォームを作成することです。この部分クラス形式は、現在作業中のコードです。このコードが完成したら、名前を変更するか、コードを他のソース コード ファイルに移動できます。

さらに、ユーザーコントロールも作成します。これにはコードの再利用という利点があり、多くの機能がフォームから移動されます。http://msdn.microsoft.com/en-us/library/6hws6h2t.aspxの「.NET Framework を使用したカスタム Windows フォーム コントロールの開発」を参照してください。

http://www.codinghorror.com/blog/2007/12/nobody-cares-what-your-code-looks-like.html で、 Nobody Cares What Your Code Looks Likeをチェックしてください。「整理」する前に考えておきたいこと。

于 2010-06-16T09:55:52.613 に答える
1

Model-View-Presenter パターンをご覧ください: http://en.wikipedia.org/wiki/Model_View_Presenter

このパターンを使用すると、フォームのコード ビハインドには、主にプレゼンターへの単純なカスケード呼び出しが含まれている必要があります。これにより、モデルが変更され、イベントがビューにカスケードされます (実装によっては、プレゼンターを介する場合もあります)。

要点: フォーム (ビュー) に状態情報を含めないでください。これはプレゼンターにあり、データが指定されたコントラクトに準拠している限り、どこからデータを取得するかを気にする必要はありません。これにより、プレゼンターで状態とデータを簡単にテストできるため、テスト容易性が向上し、PLAF、同じデータの異なるプレゼンテーションなどを可能にするビューが分離されます。

幸運を :)

于 2010-06-16T09:53:19.127 に答える
1

いくつかの簡単な提案:

すべての非 UI コードをフォームから移動するようにしてください。可能であれば、実際のフォームに GUI コードのみを配置する必要があります。プロパティに副作用がある場合、それはおそらく関数である必要があります。State プロパティはほぼ確実にメソッドである必要があり、コードを別のメソッドに分割できるかどうかを確認して、状態ごとに 1 つの関数呼び出しだけにする必要があります。

于 2010-06-16T09:55:17.523 に答える
0

私は次のようなリージョンを使用します:

#Region "_Edit"
    Private Sub _edit_VisibleChanged(...) Handles _edit.VisibleChanged
    End Sub
#End Region

上から下に、私のフォームコードには次のものがあります。

  • プライベート宣言
  • 友達のプロパティ
  • 友達の潜水艦
  • 私有地
  • プライベート潜水艦
  • イベント
  • プライベートフォーム/クラスのイベントハンドラー

Stateプロパティを分割する必要があるようです。あるいは、コードを他のクラスやルーチンに移動して、複雑さをより隠しているようです。

于 2010-09-30T15:39:26.677 に答える
0

これは、非常に頻繁に使用されるアーキテクチャ パターンへのリンクです。

http://en.wikipedia.org/wiki/Model_View_ViewModel

他のアーキテクチャ パターンもいくつか調べて、このパターンについてさらに調べたり、サンプル コードを調べたりします。

于 2010-06-16T09:52:36.647 に答える
0

最初にコードを分析して、アプリケーション ロジックと UI ロジックを区別する必要があります。それらの両方が同じファイルにあることはありません。状態プロパティは間違いなく UI ロジックではないため、最初にフォームから移動してください。これは、フォーム コードをクリアするのに役立ちます。

次に、いくつかの設計パターンと原則について読んでください。ここでいくつかの素晴らしい例を見つけることができます。あなたの場合、行動パターン、より具体的には状態とメディエーターのパターンをチェックします。これらは問題を解決するための特効薬ではありませんが、アプリケーションと UI ロジックを分割する方法をよりよく理解できるはずです。

于 2010-06-16T10:09:36.373 に答える
0

私は、ユーザー コントロールまたはカスタム コントロールにできるだけ多くのコードを配置する傾向があります。コンポーネントは再利用しやすくなり、フォームコードは読みやすくなりました。

ユーザーコントロールは、動的部分をフォームコードから簡単に分離できるようにするイベントを処理および公開することもできます。

タイマーのように、フォームには表示されないカスタム コントロールを作成することもできます。

于 2010-06-16T10:15:52.673 に答える