2017-10-13 22 views
0

私はこのアーキテクチャを初めてWinformで実装しようとしています。だから、私にとってはシンプルだが非常に重要な質問がある。 簡単な例を考えてみましょう。私はフォームがユーザーリストを取得し、電話番号の変更を許可するようにします。 Winform Appの3層アーキテクチャ

public Form1() 
{ 
    InitializeComponent(); 
    UserService _userService = new UserService(); 
    listBoxUsers.DataSource = _userService.GetAllUsers(); 
} 
class User 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Phone { get; set; } 
} 
class UserService 
{ 
    UserRepository _userRepository=new UserRepository(); 
    public Dictionary<int, string> GetAllUsers() 
    { 
     DataTable dtbl= _userRepository.AllUsers(); 
     //Some code here 
     return dict; 
    } 
} 
class UserRepository 
{ 
    public DataTable AllUsers() 
    { 
     //Sql query 
     return dtbl; 
    } 
} 

今lisboxでユーザを選択することにより、私は電話番号のようないくつかの情報を表示することができるよ私は、これが最初のステップを持っている(簡略化及びIは、通常、インタフェースを使用します)。電話番号を変更するときは、SQLデータベースを更新するためにUpdatePhoneNumberというメソッドが必要です。 しかし、どこに配置するのですか? UserまたはUserService(私はSQLクエリについて、ロジックだけは話しません) その後、フォームに表示するには、このユーザープロパティに(ここや他のどこかの)アプリケーションにアクセスする方法はありますか? _user.Id(ユーザーはフォームでインスタンス化する必要があります)または_userServiceを実装します。このIDはUser.IDを取得します(この場合、FormはUserServiceクラスのみを認識します)。 貴重なご協力ありがとうございます

+1

なぜ 'GetAllUsers()'は 'Dictionary 'を返しますか?私は 'Dictionary '(あるいは単に 'IEnumerable ')を期待しています。 'User'は*単なる*データ転送オブジェクトです。だから、電話番号*や他のプロパティ*を変更するときは、DTOで変更して、サービスやリポジトリに 'Update(User user)'のようなメソッドを置いてください。何か変更があったかどうかをチェックするサービスと、実際にデータベースに変更を書き込むリポジトリ(または何らかのストレージの種類)を担当するサービス。 – Corak

答えて

0

ユーザーのデータを操作するすべてのメソッドをユーザークラスに入れます。ユーザーが何をすることができるのか質問してください。 UserServiceのユーザーを制御するロジックをGetUserById、GetAllUsers、CreateUserなどのように入れます。 ユーザーが実行できるすべてのメソッドをUserクラスに置きます。 または私は最近、この種のものを構築していました。私はUserとUserServicesを1つにマージし、UserServicesクラスのメソッドを静的にしました。

このヘルプが必要です。

+0

"User"と "UserService"をマージすることは、ロジックをレイヤーに分割する意図とはまったく反対です。また、[単一責任の原則](https://en.wikipedia.org/wiki/Single_responsibility_principle)([SOLID]の "S"(https://en.wikipedia.org/wiki/SOLID_(object- oriented_design)))) – Corak

+0

大規模なプロジェクトでのみ意味があり、ユーザーのロジックに関連するすべてのものがユーザーの中にあるSingle Resp Principleには違反していません。 –

+0

これは、小さなテストアプリケーションに最初に適用して、動作しているものとできていないものを学習し、後で大規模なプロジェクトで使用することによって、OPの「階層化された」構造に入るように聞こえました。そして、オブジェクトがそれ自身の検索/永続性の責任を負うことは、** SRPの違反です。あなたは "App"クラスを一つも持っておらず、すべてがアプリロジックと関連しているので、そこにすべてを入れます。 – Corak

0

基本的な3層アプリの外観は次のとおりです。

  1. UI(フォームとUIサポート・オブジェクト)
  2. BLL(GetAllUsers、SaveUser、は、deleteuserなど)
  3. データ(ADO、EFなど)あなたの特定の場合において

、あなたは本当にマスターディテールのコンセプトを探しています。あなたは、ユーザーのリストを表示するマスター通常、1つは

// Master 
var _userList = Service.GetAllUsers(); // List<UserModel> 
userGrid.Datasource = _userList; 

私はここでそれを説明しませんが、グリッド上のそのクリックが詳細コントロールが移入されているになりますので、あなたは、バインディングを設定することができます。または手動で

// detail 
UserModel model = master._userList[currIndex]; 
txtFirstName.Text = model.FirstName; 
txtPhone.Text = model.Phone; 
// . . . . 

さて、もちろん、あなたがテキストボックスを変更し、ユーザーを保存しようとしている...

// detail 
UserModel model = master._userList[currIndex]; 
Service.SaveUser(model); 
Master.Reload(); 

これは、これがどのように行われるか、一般的な考え方です。あなたが従うならば、あなたは別個の層を持っています。 UIはDataを呼び出すServiceを呼び出します。たとえば、BLLは

// Service 
private IUserDataProvider _provider; 

public List<UserModel> GetAllUsers() 
{ 
    var data = _provider.Get<User>(); 
    // massage your 'data' and return List<UserModel> 
    . . . . 
} 

プロバイダは、いくつかの不要なデータを返すことがあります持っているので、あなたはそれをトリミングし、適切なデータのみを返すようにBLLを使用することができます。しかし、あなたはプロバイダが内部でやっていることを知らない。 Ado.netまたはEntity Frameworkを実行している可能性があります。したがって、層の真の分離。

関連する問題