Гость
Форумы / Разработка информационных систем [игнор отключен] [закрыт для гостей] / Слой доступа к данным в виде одного огромного класса / 25 сообщений из 28, страница 1 из 2
27.10.2006, 08:01
    #34085675
November
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
Добрый день, уважаемые коллеги.
В своих проектах, при реализации web-приложений, всякий раз сталкиваюсь с одной и той же проблемой. При разделении кода на слои (представления данных, бизнес логики и доступа к данным), весь третий слой сводится к одному громадному классу. Он содержит десятки методов доступа к данным. Это бесконечная вериница чего-то типа:
CreateNewMember(…)
CreateNewSet(…)
.
DeleteMember(…)
DeleteSet(…)
.
UpdateSomeData(…)
и т.д…
В предпоследнем и последнем проектах этот класс включал 1520 и 1600 строк соответственно.
Примеры реализации из литературы грешат тем же вырождением слоя в один класс, но из-за "игрушечности" классы не разрастаются до монстров. Возьмем другой пример - учебный проект по ASP.NET 2.0 под названием TimeTracker. В нем класс доступа к данным SQLDataAccess тянет на 700 строк кода.
Вот такая проблема. Мне кажется что данный подход неэстетичен и неудобен. Однако, другие решения приводят к усложнению, потере ясности архитектуры проекта. Подскажите, пожалуйста, выход.
...
Рейтинг: 0 / 0
27.10.2006, 09:42
    #34085840
мод
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
NovemberВ своих проектах, при реализации web-приложений, всякий раз сталкиваюсь с одной и той же проблемой. При разделении кода на слои...
А не надо делить на слои, и проблемы не будет. См. 4GL. Дело в том, что логика неотделима от данных. Делить надо не по слоям, а по функциям.
...
Рейтинг: 0 / 0
27.10.2006, 10:21
    #34085960
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
мод NovemberВ своих проектах, при реализации web-приложений, всякий раз сталкиваюсь с одной и той же проблемой. При разделении кода на слои...
А не надо делить на слои, и проблемы не будет. См. 4GL. Дело в том, что логика неотделима от данных. Делить надо не по слоям, а по функциям.
ну почему неотделима?
XML, например.
...
Рейтинг: 0 / 0
27.10.2006, 10:42
    #34086062
мод
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
Petro123ну почему неотделима?XML, например.
XML это данные, а где логика ?
А в функц. программировании логика и данные - это одно и то же (попробуй раздели :) )
...
Рейтинг: 0 / 0
27.10.2006, 11:07
    #34086164
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
мод Petro123ну почему неотделима?XML, например.
XML это данные, а где логика ?
А в функц. программировании логика и данные - это одно и то же (попробуй раздели :) )
зайди на форум XML и спроси (я в Web не силён).
Могу предположить, что логика в скриптах.


HTML (представление)
|
XSD (транслятор)
|
XML (данные)
...
Рейтинг: 0 / 0
27.10.2006, 14:37
    #34087188
AlexTheRaven
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
NovemberПодскажите, пожалуйста, выход.
Выход - соблюдайте инкапсуляцию. Пока не вы поддерживаете этот класс и десятки методов работают достаточно хорошо - неудобство поддержки это не ваша головная боль. А эстетичность не является целью коммерческого программирования.

Если же пишете сами - кроме огромного класса, другого выхода я не вижу. А в огромном классе не вижу проблемы. Разве что... Не пользуйтесь классами, делайте в виде библиотеки с процедурами и функциями :) . Хотя по сути будет почти то же самое, просто с другим названием, но восприниматься будет проще :) .
...
Рейтинг: 0 / 0
27.10.2006, 14:51
    #34087264
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
NovemberПодскажите, пожалуйста, выход.
почитать книги про ООП (наследование)
...
Рейтинг: 0 / 0
27.10.2006, 21:25
    #34088247
SergGol
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
Так что хужее: потяря ясности и усложении или большое количество строк кода?
С другой стороны: если больше нагрузки уходит на более низкий уровень (доступ), потенциально менее подверженный измененям, то что здесь плохого?
...
Рейтинг: 0 / 0
27.10.2006, 21:28
    #34088249
SergGol
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
Кстати, возьмите любой прикладной кусок из ООП, что там будет наиболее часто встречающимся? Правильно inherited то-то. Значит внизу написано верно.
...
Рейтинг: 0 / 0
28.10.2006, 03:33
    #34088439
November
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
При отсутствии более элегантных решений, данное применимо и жизнеспособно. Просто, хотелось бы увидеть альтернативу.

P.S. Сам вопрос появился из ощущения ассиметричности применяемого решения, какой то его непропорциональности, что ли. Два других слоя состоят из множества классов, а этот...
...
Рейтинг: 0 / 0
28.10.2006, 10:12
    #34088493
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
>November
>P.S. Сам вопрос появился из ощущения ассиметричности применяемого решения ...

А какая необхдимость(функциональная) в этом классе?

С уважением, Владимир.
...
Рейтинг: 0 / 0
28.10.2006, 13:31
    #34088590
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
NovemberПри отсутствии более элегантных решений, данное применимо и жизнеспособно. Просто, хотелось бы увидеть альтернативу.

P.S. Сам вопрос появился из ощущения ассиметричности применяемого решения, какой то его непропорциональности, что ли. Два других слоя состоят из множества классов, а этот...
не знаю про Ваш язык, но в Delphi именно в классах доступа к данным всё чётко - полный ООП.
Например, запись картинки BLOB в бинарное поле на сервере проходит через ....надцать наследников и классов.
Да и самому писать такие библиотеки не надо (всё уже написано до вас).
Сходите на форум по вашему ЯП.
...
Рейтинг: 0 / 0
28.10.2006, 16:35
    #34088713
November
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
ВМоисеев> А какая необхдимость(функциональная) в этом классе?


Данный класс реализует слой доступа к источнику данных. Благодаря этому слою возможна абстракция "источника данных". Остальные слои системы могут ничего не знать о конкретной реализации этого источника. Это приводит к упрощению дальнейшей модификации системы. Мы, например, безболезненно можем в последствии изменить СУБД на файлы, содержащие XML, не затрагивая других частей системы. Они, как и прежде будут обращаться к данным через вызов методов класса доступа к данным (GetSomeData(…) или, например CreateSomeMember(…)).
С уважением, November.
...
Рейтинг: 0 / 0
28.10.2006, 17:14
    #34088733
November
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
Petro123 ... не знаю про Ваш язык, но в Delphi именно в классах доступа к данным всё чётко - полный ООП.


С целью облегчения дальнейшей поддержки кода приложения, все те классы доступа к данным, о которых Вы говорите, должны быть собраны в один слой системы (иначе их вызовы "расползутся" по всему коду программы). Вот этот слой и приобретает вид одного огромного класса.
Что касается названных вами библиотек, то я ими, несомненно, пользуюсь. В .Net это технология ADO.NET, в Java -- JDBC. Вот только их применение надо ограничить одной частью системы, и этой частью и становится один "монстрообразный" класс.

С уважением, November.
...
Рейтинг: 0 / 0
28.10.2006, 21:05
    #34088840
М.Голованов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
NovemberВ предпоследнем и последнем проектах этот класс включал 1520 и 1600 строк соответственно.
Примеры реализации из литературы грешат тем же вырождением слоя в один класс, но из-за "игрушечности" классы не разрастаются до монстров. Возьмем другой пример - учебный проект по ASP.NET 2.0 под названием TimeTracker. В нем класс доступа к данным SQLDataAccess тянет на 700 строк кода.
Вот такая проблема. Мне кажется что данный подход неэстетичен и неудобен. Однако, другие решения приводят к усложнению, потере ясности архитектуры проекта. Подскажите, пожалуйста, выход.

В моем текущем проекте этот класс включает 7848 строк кода. И это при том, что он реализует ТОЛЬКО методы, используемые как минимум дважды. Методы, используемые только однажды, пишутся по месту с использованием ресурсов этого класса (ORM сессия и соединение с БД).

Ну и что? Это удобно, а значит, правильно.
...
Рейтинг: 0 / 0
30.10.2006, 11:11
    #34090336
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
November Petro123 ... не знаю про Ваш язык, но в Delphi именно в классах доступа к данным всё чётко - полный ООП.

С целью облегчения дальнейшей поддержки кода приложения, все те классы доступа к данным, о которых Вы говорите, должны быть собраны в один слой системы (иначе их вызовы "расползутся" по всему коду программы).
совершенно неправильный вывод.
Т.е. если у вас 10 маленьких, но удобных классов, то ОНИ не должны расползаться? Вы считаете, что один:
Код: plaintext
Class = СуперПуперКлассНаВсеСлучаи
лучше?
...
Рейтинг: 0 / 0
30.10.2006, 15:59
    #34091698
gybson
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
Третий слой должен вообще сводиться буквально к 2м методам
- Execute
- ExecuteNonQuery

:D

И они уже все практически написаны. CreateMember e.t.c. это уже БЛ
...
Рейтинг: 0 / 0
06.11.2006, 18:16
    #34107493
GoldDragon
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
Я вот прочитал всё что здесь написано и честно говоря не совсем понял, что значит 1 большой класс и почему он лучше для работы с различными источниками данных, и с различными таблицами. Я не говорю, что сам технология не верна или что-то в этом роде, просто я не совсем понял как можно организовать нормальную работу этого слоя в одном классе. Мог бы ты дать мне статьи почитать об этом или на примере объяснить как это раборает.
К примеру, у меня есть 2 таблицы X и Y. На business layer у меня есть 2 объекта X и Y, которые должны получать информацию от data layer. Как именно ты организуешь этот уровень в 1-м классе, для различных баз данных и который бы позволял различные операции для этих 2-х объектов?
...
Рейтинг: 0 / 0
10.11.2006, 10:24
    #34118443
AlexTheRaven
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
November<..>Вот такая проблема. Мне кажется что данный подход неэстетичен и неудобен. Однако, другие решения приводят к усложнению, потере ясности архитектуры проекта. Подскажите, пожалуйста, выход.<..>
(После наступившего при частичном прочтении книги "Domain Driven Design" by E.Evans частичного просветления:) )
Выход - не совмещать в одном объекте FACTORY и REPOSITORY. FACTORY, которые создают объекты, должно быть столько же, сколько AGREGATES + ENTITY + VALUE OBJECTS. REPOSITORY должен быть один, и как раз реализовывать executeQuery() и executeNonQuery().
...
Рейтинг: 0 / 0
10.11.2006, 13:47
    #34119432
gybson
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
(После наступившего при частичном прочтении книги "Domain Driven Design" by E.Evans частичного просветления:) )
Выход - не совмещать в одном объекте FACTORY и REPOSITORY. FACTORY, которые создают объекты, должно быть столько же, сколько AGREGATES + ENTITY + VALUE OBJECTS. REPOSITORY должен быть один, и как раз реализовывать executeQuery() и executeNonQuery().


Ну не так вот конечно просто. Если есть задумка о кроссплатформенности, то при проектировании надо сразу заложить блок трансляции запросов.
...
Рейтинг: 0 / 0
11.11.2006, 09:17
    #34121011
November
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
AlexTheRaven
Выход - не совмещать в одном объекте FACTORY и REPOSITORY. FACTORY, которые создают объекты, должно быть столько же, сколько AGREGATES + ENTITY + VALUE OBJECTS. REPOSITORY должен быть один, и как раз реализовывать executeQuery() и executeNonQuery().

Другими словами, Вы предлагаете разделить весь слой доступа к данным на два подслоя. Первый будет содержать множество классов factory. Второй будет состоять из одного класса.
На первый взгляд, вполне разумная альтернатива. Возможно, следует сделать все классы factory-подслоя наследниками одного суперкласса, который "снабдит" их необходимыми общими методами.
С уважением, November.
...
Рейтинг: 0 / 0
11.11.2006, 09:28
    #34121017
November
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
GoldDragonМог бы ты дать мне статьи почитать об этом или на примере объяснить как это раборает.
Скачайте код Time Tracker Starter Kit от майкрософтовского ASP.NET 2.0 msdn.microsoft.com/vstudio/express/vwd/starterkit/ (в нем всего половина мегабайта) и посмотрите на класс из файла \App_Code\DAL\SQLDataAccessLayer.cs. Думаю, все станет понятно.
С уважением, November.
...
Рейтинг: 0 / 0
11.11.2006, 10:08
    #34121038
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
>November
>Данный класс реализует слой доступа к источнику данных.

А почему нельзя для каждого "абстрактного" источника данных свой класс и один общий для всех в слое - "интерфейсный" ?

С уважением, Владимир.
...
Рейтинг: 0 / 0
11.11.2006, 12:55
    #34121124
just kidding
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
Для примера посмотрим Time Tracker Starter Kit:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
public class Category {
  ...
  public bool Delete() { 
      if (this.Id > DefaultValues.GetCategoryIdMinValue()) {
        DataAccess DALLayer = DataAccessHelper.GetDataAccess();
        return DALLayer.DeleteCategory(this.Id);
      }
      else
        return false;
   }
  ...
}
//---------------------
public class DataAccessHelper { // Factory Pattern
    public static DataAccess GetDataAccess() {
       ...
       DataAccess dc = (DataAccess)Activator.CreateInstance(dataAccessType);
       return (dc); // кстати, почему здесь не Singleton?
    }
}
//---------------------
 public abstract class DataAccess {
...
    public abstract bool DeleteCategory(int categoryId);
...
}
//---------------------
public class SQLDataAccess : DataAccess { // Facade pattern
   ...
   private const string SP_CATEGORY_DELETE = "aspnet_starterkits_DeleteCategory";
   ...
   public override bool DeleteCategory(int categoryId) {
      if (categoryId <= DefaultValues.GetCategoryIdMinValue())
        throw (new ArgumentOutOfRangeException("categoryId"));

      SqlCommand sqlCmd = new SqlCommand();

      AddParamToSQLCmd(sqlCmd, "@ReturnValue", SqlDbType.Int,  0 , ParameterDirection.ReturnValue, null);
      AddParamToSQLCmd(sqlCmd, "@CategoryIdToDelete", SqlDbType.Int,  0 , ParameterDirection.Input, categoryId);

      SetCommandType(sqlCmd, CommandType.StoredProcedure, SP_CATEGORY_DELETE);
      ExecuteScalarCmd(sqlCmd);

      int returnValue = (int)sqlCmd.Parameters["@ReturnValue"].Value;
      return (returnValue ==  0  ? true : false); // wtf? :)))
  }
  ...
  private void ExecuteScalarCmd(SqlCommand sqlCmd) {
      if (ConnectionString == string.Empty)
        throw (new ArgumentOutOfRangeException("ConnectionString"));
      if (sqlCmd == null)
        throw (new ArgumentNullException("sqlCmd"));
      using (SqlConnection cn = new SqlConnection(this.ConnectionString)) {
        sqlCmd.Connection = cn;
        cn.Open();
        sqlCmd.ExecuteScalar();
      }
  }
  ...
}

Имеем такую цепочку вызовов:
1-й уровень - приложение : category.Delete()
2-й уровень - бизнес-слой (класс Category): DataAccessHelper.GetDataAccess().DeleteCategory(this.Id)
3-й уровень - SQL слой доступа к данным: sqlCmd.executeScalar()
4-й уровень - БД: exec aspnet_starterkits_DeleteCategory

Фактические, класс SQLDataAccess - просто большой библиотечный модуль, реализующий функции доступа, с учетом специфики метода хранения SQL, причем почти все функции можно разделить на блоки логически связанных, которые работают с одним типом бизнес-объектов (одной таблицей, view, группой ХП etc).

Для библиотек - большое количество функций не порок :)

А оформление этого модуля в виде одного большого класса, с малосвязанными между собой блоками, вызвано скорее особенностями конкретного языка программирования: статическая типизация, возможность множественного наследования только интерфейсов, но не реализации.

Например, на Ruby, где реализованы dynamic dispatch ( obj.respond_to?( method_name ), obj.send( method_name, *args) ), и mixins, соответствующий класс мог бы быть оформлен примерно следующим образом:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
class SQLDataAccess

  include SQLDataHelper

  include CategorySQLDataAccess
  include PersonSQLDataAccess

  attr_accessor :connection_string

  def initialize( conn_string)
    @connection_string = conn_string
  end
end

module SQLDataHelper
  def exec_scalar_cmd( sql_cmd )
    cn =SqlConnection.new(connection_string)
    sql_cmd.connection =  cn
    cn.open()
    sql_cmd.execute_scalar()
  end

  def add_param_to_sql_cmd(sql_cms, param_id, sql_type, param_size, param_direction, param_value)
    # [snipped]
  end

  def set_command_type(sql_cmd, reader, list)
    # [snipped]
  end
end

module CategorySQLDataAccess
   SP_CATEGORY_DELETE = "aspnet_starterkits_DeleteCategory"

   def delete_category(category_id)
     sql_cmd = SqlCommand.new
     add_param_to_sql_cmd(sql_cmd, "@ReturnValue", SqlDbType.Int,  0 , ParameterDirection.ReturnValue, nil)
     add_param_to_sql_cmd(sql_cmd, "@CategoryIdToDelete", SqlDbType.Int,  0 , ParameterDirection.Input, category_id)
     set_command_type(sql_cmd, CommandType.StoredProcedure, SP_CATEGORY_DELETE)
     execute_scalar_cmd(sql_cmd)
     return_value = sql_cmd.parameters["@ReturnValue"].value
     return (return_value ==  0 )
   end
end
Но это уже больше из соображений удобства сопровождения кода :)

Еще можно посмотреть подход типа Rails ActiveRecord , где "тупые" часто используемые методы (getters/setters для атрибутов, create, update, delete, find, find_by_some_field etc.) генерируются автоматически, вопросы конкретной реализации взаимодействия с хранилищем (получение метаданных для генерации, трансляция запросов) отданы на откуп ConnectionAdapter'ам.
...
Рейтинг: 0 / 0
11.11.2006, 15:27
    #34121233
November
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Слой доступа к данным в виде одного огромного класса
ВМоисеевА почему нельзя для каждого "абстрактного" источника данных свой класс и один общий для всех в слое - "интерфейсный" ?
Мне кажется, что несколько классов для "абстрактных" источников данных, как правило, не требуется. Ведь типичное приложение работает с единственным источником.
P.S. Возможно, я не совсем понял, что значит "абстрактный" источник данных.
С уважением, November.
...
Рейтинг: 0 / 0
Форумы / Разработка информационных систем [игнор отключен] [закрыт для гостей] / Слой доступа к данным в виде одного огромного класса / 25 сообщений из 28, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]