Страницы

Поиск по вопросам

суббота, 27 октября 2018 г.

Помогите разобраться с отделением бизнес-логики от формы

Я только начинаю осваивать C#. Сейчас пытаюсь разобраться в аспектах проектирования приложения для работы с базами данных. Практически каждый раз я слышу такую фразу "бизнес-логика должна существовать отдельно от формы". Но я не совсем понимаю как этого добиться при программировании WinForms?
Посоветуйте пожалуйста исчерпывающее руководство или литературу на этот счет.
UPD:
На данный момент удалось понять, что при использовании WinForms необходимо использовать паттерн MVP. И единственный пример использования MVP для WinForm, по которому удалось построить рабочее приложение, я смог найти вот в этом топике Как начать пользоваться MVP + WinForms?. Следую изложенной в нём информации у меня получилось следующее приложение.
Можете оценить, насколько у меня получилась правильная реализация применения паттерна MVP и отделения бизнес-логики от формы?
View
using System.Linq;
namespace EFCodeFirstMVP { interface IView { void SetData(IQueryable items); } }
using System; using System.Linq; using System.Windows.Forms;
namespace EFCodeFirstMVP { public partial class Form1 : Form, IView { private readonly GoodsPresenter presenter;
public Form1() { presenter = new GoodsPresenter(this, new GoodsModel()); InitializeComponent(); }
public void SetData(IQueryable items) { dataGridView1.DataSource = items.ToList(); }
private void Form1_Load(object sender, EventArgs e) { presenter.LoadData(); } } }
Presenter
namespace EFCodeFirstMVP { class GoodsPresenter { private readonly IView view; private readonly IModel model;
public GoodsPresenter(IView view, IModel model) { this.view = view; this.model = model; }
public void LoadData() { var data = model.LoadData(); view.SetData(data); } } }
Model
using System.Linq;
namespace EFCodeFirstMVP { interface IModel { IQueryable LoadData(); } }
using System.Linq;
namespace EFCodeFirstMVP { class GoodsModel : IModel { public IQueryable LoadData() { Context context = new Context();
var items = from Items in context.Goods select Items;
return items; } } }
Data
using System.Data.Entity;
namespace EFCodeFirstMVP { class Context: DbContext { public DbSet Goods { get; set; } public DbSet GoodsList { get; set; }
public Context() { Database.SetInitializer(new CreateDatabaseIfNotExists()); } }
public class Goods { public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } public string Barcode { get; set; } public int Price{ get; set; } } }


Ответ

Окей, давайте попробуем поговорить об этом вне привязки к WinForms.
Смотрите. У вас есть две различные вещи: внутреннее поведение программы, и то, как она показывает это пользователю. Представьте себе, чтобы вы пишете программное обеспечение радара. У вашей программы внутри есть список отслеживаемых самолётов. Вы принимаете информацию с датчиков, обсчитываете её, принимаете решение о том, возник новый самолёт, или ложная цель, или известный вам самолёт переместился. Всё это происходит внутри, и для этого взаимодействие с пользователем не так уж и обязательно. Это внутренняя часть программы, модель
Теперь, вам нужно донести эту информацию до оператора. В каком виде вы будете представлять информацию — в виде распечаток зелёного текста на чёрном фоне, или в виде трёхмерной голографической визуализации — не так уж важно, и модель по существу не зависит от этой части.
Поэтому вы должны писать модель так, чтобы модель ничего не знала о представлении. Это не то, чтобы строго обязательно, но это позволяет разделить программу на независимые части, и даёт лёгкость работы с ними.
Здесь ещё остаются открытыми вопросы о том, как передавать действия пользователя модели, но это отдельная тема.
Посмотрим на более приземлённый пример: работа с базой данных.
Точно так же у вас есть модель: база данных, и операции над ней, которые вы собираетесь делать. Это всё организуется в модуль, возможно, навешивается сверху синхронизация и асинхронность, на этом модель можно считать оконченной.
Представление должно просто
показывать пользователю часть модели принимать у пользователя команды, и доставлять их модели после обновления модели показывать обновлённую информацию
Обычно выделяют ещё и промежуточный уровень — бизнес-логику, контроллер, view model, которые занимаются пинанием модели, с тем чтобы представление занималось только представлением.

Комментариев нет:

Отправить комментарий