Winform应用程序中的3层体系结构
我试图在Winform中首次实现此体系结构。所以我对我有一个简单但非常重要的问题。 举一个简单的例子。我希望表单能够检索用户列表并允许修改电话号码。 我有这样的第一步骤(简化和我通常使用的接口)Winform应用程序中的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用户,我能够显示一些信息作为电话号码。当我更改电话号码时,我需要一个名为UpdatePhoneNumber的方法来更新SQL数据库。 但是,它放在哪里? User或UserService(我不谈论SQL查询,只是逻辑) 然后,如何访问(此处或应用程序中的其他位置)此用户属性以将其显示在表单中?直接使用_user.Id(用户必须在表单中实例化)或实现一个_userService。检索User.ID的id(在这种情况下,Form只知道UserService类)。 非常感谢您的宝贵帮助
将在用户类中的用户数据工作的所有方法。问自己这个问题用户可以做什么?将用户控制在UserService中的所有逻辑,如GetUserById,GetAllUsers,CreateUser等.. 将用户可以在User类中执行的所有方法。 或者最近我正在构建这样的事情,我将User和UserServices合并为一个,并使UserServices类方法为静态,这样我就可以在没有用户实例的情况下访问它们。
希望得到这个帮助。
“合并”“用户”和“用户服务”与将逻辑分成层的意图完全相反。它也违反[单一责任原则](https://en.wikipedia.org/wiki/Single_responsibility_principle)([SOLID]中的“S”(https://en.wikipedia.org/wiki/SOLID_(object- oriented_design))) – Corak
只对大型项目有意义,它仍然不违反Single Resp Principle cuz与用户逻辑有关的所有内容都在用户中。 –
听起来像OP想要“进入”分层体系结构,首先将其应用于小型测试应用程序,以了解什么可行,哪些不可行,然后可能稍后将其用于大型项目。有一个对象负责它自己的检索/持久性**是违反SRP的。你没有一个“App”类,并把所有内容放在那里,只是因为它“与应用逻辑有关”。 – Corak
这是您的基本3层应用程序的样子。
- UI(您的形式和UI支持对象)
- BLL(GetAllUsers,SaveUser,DeleteUser等)
- 数据(ADO,EF等)
在您的特定情况下,你真的在寻找Master-detail概念。在那里你显示的用户列表的主通常是一个
// 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();
这是一般的想法,如何做到这一点。如果你遵循,你有不同的层次。用户界面调用服务,调用数据。例如,你有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。因此,层的真正分离。
为什么'GetAllUsers()'返回'Dictionary'?我期望有一个“字典”(或者甚至只是一个“IEnumerable ”)。 'User'就是*数据传输对象。因此,当您更改电话号码*或任何其他属性*时,只需在DTO中更改它,然后在服务和存储库中使用类似“更新(用户用户)”的方法。负责检查是否有任何更改以及存储库实际将更改写入数据库(或任何类型的存储)的服务。 –
Corak