Розмежування отримання даних та об’єктів бізнесу між шарами DAL та BLL


9

Я зробив кілька досліджень, перш ніж розміщувати це питання. Серед інших запитань чи публікацій, одне із них подано нижче. Я не міг зрозуміти, як визначити ..

Бізнес-об'єкти в рівні доступу до даних

У мене є сховище, і бізнес-шари викликають сховище для отримання даних. Наприклад, скажіть, що у мене є такі класи для BLL та DAL:

class BllCustomer
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public BllAddress Address {get; set;}
}

class BllAddress
{
     public int AddressId {get; set;}
     public String Street {get; set;}
     public String City {get; set;}
     public String ZipCode {get; set; }
}

class DalCustomer 
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public int AddressID {get; set;}
}

class DalAddress
{
     public int AddressId {get; set;}
     public String Street {get; set;}
     public String City {get; set;}
     public String ZipCode {get; set; }
}

Якщо BLL хоче отримати об’єкт Customer, він зателефонує GetCustomerById (customerId) у DAL.

Наступні мої проблеми, я не міг зрозуміти:

  1. Я не можу зрозуміти, як визначити, який об’єкт повинен повернути GetCustomerById в DAL? Чи повинен повернути BllCustomer або DalCustomer?

  2. Де слід знаходити (та / або перетворювати на об’єкт Бізнес) адресу, пов’язану із замовником?

Якщо DAL повертає об'єкти Dal, то логіка для отримання та заповнення адреси може бути лише в BLL. Якщо DAL повертає об'єкти BLL, то логіка для отримання та заповнення адреси може бути або в BLL, або в DAL. Наразі DAL повертає бізнес-об'єкти, і логіка заповнення його є в DAL.

З того, що я прочитав, я здогадуюсь, що немає правильного чи неправильного. Із наведеного вище посилання є люди, які говорять в одну сторону, а інші говорять по-іншому. Але як визначити, що найкраще підходить для мого випадку?

Будь-яка допомога буде вдячна.


2
Перше моє запитання було б: це застаріла заявка? Існує безліч рамок ORM, які роблять такий код застарілим, і я б закликав вас розглянути такий фреймворк ...
JDT

@JDT Я не впевнений, що ти маєш на увазі, я використовую Entity Framework і маю саме таку проблему. Як я розумію, ви не повинні використовувати свій ORM як об’єкти домену, тож де проводиться переклад?
псевдокодер

Чому ваша рамка ORM також не повертає об'єкти, які є об'єктами домену?
JDT

3
@JDT ORM (EF у цьому випадку) повертає класи сутностей, які представляють, як правило, одну таблицю бази даних на клас. Зазвичай це схоже на, але не обов’язково те саме, що і доменні класи. Можливо, ви просто говорите, що нормально використовувати класи ORM як доменні класи? Я читав у багатьох місцях, що це не-ні.
псевдокодер

Відповіді:


5

Я не можу зрозуміти, як визначити, який об’єкт повинен повернути GetCustomerById в DAL? Чи повинен повернути BllCustomer або DalCustomer?

Він повинен повернути об’єкт DalCustomer , повернення об'єкта BllCustomer порушить принцип єдиної відповідальності . Ви можете розглядати об’єкт DalCustomer як інтерфейс або контракт, спожитий бізнес-рівнем (або споживачем). Фактично, якщо він повертає BllCustomer, DAL повинен обслуговувати кожен об'єкт бізнес-рівня, який його викликає або міг би потенційно викликати його.

Де слід знаходити (та / або перетворювати на об’єкт Бізнес) адресу, пов’язану із замовником?

Перетворення повинно здійснюватися у моделі перегляду чи менеджері. Вам потрібно мати посередника, щоб зателефонувати в службу чи компонент доступу до даних. Якщо ви відчуваєте потребу, можете здійснити конверсію у вашому об'єкті BllCustomer . Але тоді, коли ви замінюєте свій DAL з MSSQL на Oracle, наприклад, ваш повернутий об'єкт (або інтерфейс) повинен залишатися незмінним.

Переважно рівень вашого бізнесу також повинен бути незалежним від вашого рівня даних. Бізнес-шар відповідає за правила вашого бізнесу. Саме тут ви додасте свої перевірки, використовуючи рамки перевірки для виконання своїх бізнес-правил.


4

Ваше сховище повинно повернути BLL або об’єкт домену. швидше за все, вам взагалі не потрібен DAL-об’єкт.

public class Customer
{
    public string Name {get; private set;}
    public Customer(string name)
    {
        this.Name = name;
    }
}

public class Repository
{
    public Customer GetCustomer(string id)
    {
        //get data from db
        return new Customer(datarow["name"]);
    }
}

Чи повинен BLL або окрема бібліотека класів відкривати інтерфейси замість конкретних класів, як Customer?
Йола

1
Ні. Його штраф за викриття конкретних класів. Корисний буде інтерфейс для сховища
Ewan

3

Як правило, DAL не знає про BLL. Подумайте про це таким чином, інша програма з іншим BLL може використовувати той же DAL. Додаток / модуль кредиторської заборгованості та додаток до дебіторської заборгованості для тієї ж компанії обмінюватимуться даними (клієнти, збори, платежі тощо). Спроба мати одну DLL, яка має знання про більш ніж один BLL, була б дуже складною і непотрібною. Це також дозволить вам змінити сховище даних, не впливаючи на BLL (до тих пір, поки ви не порушите інтерфейси).

Тепер ви можете передати об'єкт DAL до BLL або ви можете створити третій набір об'єктів: Entity. Вони містять лише ті значення, які потрібно передавати разом. DAL посилається на сутність та взаємодіє із вашим сховищем / базою даних, а BLL обробляє всю логіку та посилається на DAL.

class EntCustomer
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public BllAddress Address {get; set;}
}
class BllCustomer
{
   //reference EntCustomer, DalCustomer and handle business rules/logic
}

class DalCustomer 
{
   //reference EntCustomer and interact with data storage
}

Дякую за Ваш коментар Я згоден з вами. Я вже бачу, що наш DAL / (сховище) вже заповнений логікою, як, наприклад, якщо тип A, то перейдіть до отримання даних з таблиці B, але якщо тип C, тоді перейдіть до отримання даних з таблиці C. Але я плутаю ваш приклад за допомогою EntCustomer. У моєму випадку DalCustomer є дзеркалом таблиць у БД. Чи можете ви надати більше прикладів, як використовується EntCustomer або чому я повинен ним користуватися та користь від цього. Я думаю, щоб змінити DAL, щоб повернути DalObjects до BLL. Bll перетворить перетворення в бізнес-Objs, отримає та заповнить вкладені obj.
ShamirDaj

Чи можете ви надати більше відгуків?
ShamirDaj

Я думаю, що метою Ent-об'єктів є просто передача даних між DAL та BLL. Ваші класи DAL можуть продовжувати відображати структуру db, але ці класи будуть внутрішніми для DAL. Коли BLL запитує дані від DAL, DAL отримує необхідні DAL-об'єкти з бази даних (dalcustomer + daladdress) і конструює з них екземпляр EntCustomer і повертає його до BLL.
artokai

-1

DAL повинен бути незалежним від BL, а BL залежати від DAL. Ваш інтерфейс повинен мати доступ до даних лише через BL. Його хороша практика, якщо ви повернете DataTable або DataRow з DAL, а потім перетворите DataTable / DataRow в об'єкти (BL). Коли ваш інтерфейс повинен отримати доступ до даних, він може отримати доступ від BL. Таким чином, інтерфейс буде незалежним від імені стовпця та типу бази даних (SQL Server, Oracle ..). Таким чином ваш інтерфейс буде повністю незалежним від DAL. Особисто я віддаю перевагу назві класу на кшталт "CustomerBL", не використовуйте слово BL у просьбі імені класу.

Нижче див. Приклад коду.

//Customer Class
class BllCustomer
{
    public int CustomerId { get; set; }
    public String Name { get; set; }
    public BllAddress Address { get; set; }

    public static BllCustomer GetByCustomerId(int id)
    {
        DataRow dr = DalCustomer.GetByCustomerId(id);
        if (dr == null)
            return null;
        BllCustomer oCust = new BllCustomer();
        oCust.CustomerId = int.Parse(dr["CustomerId"].ToString());
        //Do for other class members and load values

        return oCust;
    }
}


class DalCustomer
{

    public static DataRow GetByCustomerId(int id)
    {
        //Get Data row from Database and return Datarow
        DataRow CustomerRow = GETFROMDATABASE("SELECT * from CUSTOMER");
        return CustomerRow;
    }
}

Помилка ... Чи це не означає, що ваш BLL повинен мати знання про формат / структуру ваших таблиць даних? ...
Павло
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.