Не могу въехать, как правильно спроектировать класс.
В общем случае документ состоит из шапки, с несколькими обязательными атрибутами (идентификатор, позиция во времени, номер документа, автор и т.п.) и произвольным набором дополнительных атрибутов (клиент, склад, банк и т.п.) и произвольного количества табличных частей, содержащих произвольный набор атрибутов.
Собственно атрибуты могут быть как базовыми типами (число, строка и т.п.), так и ссылочными (клиент — ссылка на справочник клиентов).
Естественно, хочется абстрагироваться от непосредственной работы с БД, т.е. создать класс, реализующий модель документа.
Первый вопрос, с которым я столкнулся, это вариант создать базовый класс документа, которому наследовать реализацию конкретного вида документа. Либо создать универсальный класс документа, который будет получать метаданные о том виде документа, с которым ему предстоит работать.
Минусы первого варинта — большое количество наследников, в которых будут похожие механизмы работы с БД, т.е. появление практически дублирующегося кода.
Минусы второго — непонятно, как в общий универсальный документ засунуть бизнес-логику, уникальную для каждого конкретного вида документов.
Технически пока не совсем четко представляю:
разруливание ссылочных атрибутов
ссылка в документе-объект-отображение;
организацию работы с метаданными.
Вообще, сумбурчик пока что...
Буду благодарен за любую инвормацию по данной теме.
... << RSDN@Home 1.1.3 stable >>
17.06.04 14:57: Перенесено модератором из '.NET' — AndrewVK
Здравствуйте, GuinPin, Вы писали:
GP>Не могу въехать, как правильно спроектировать класс. GP>В общем случае документ состоит из шапки, с несколькими обязательными атрибутами (идентификатор, позиция во времени, номер документа, автор и т.п.) и произвольным набором дополнительных атрибутов (клиент, склад, банк и т.п.) и произвольного количества табличных частей, содержащих произвольный набор атрибутов. GP>Собственно атрибуты могут быть как базовыми типами (число, строка и т.п.), так и ссылочными (клиент — ссылка на справочник клиентов). GP>Естественно, хочется абстрагироваться от непосредственной работы с БД, т.е. создать класс, реализующий модель документа. GP>Первый вопрос, с которым я столкнулся, это вариант создать базовый класс документа, которому наследовать реализацию конкретного вида документа. Либо создать универсальный класс документа, который будет получать метаданные о том виде документа, с которым ему предстоит работать. GP>Минусы первого варинта — большое количество наследников, в которых будут похожие механизмы работы с БД, т.е. появление практически дублирующегося кода. GP>Минусы второго — непонятно, как в общий универсальный документ засунуть бизнес-логику, уникальную для каждого конкретного вида документов. GP>Технически пока не совсем четко представляю: GP>разруливание ссылочных атрибутов GP>ссылка в документе-объект-отображение; GP>организацию работы с метаданными. GP>Вообще, сумбурчик пока что... GP>Буду благодарен за любую инвормацию по данной теме.
Рекомендую посмотреть книжку Martin Fowler — Patterns of Enterprise Application Architecture, она на русском вышла в этом году, вот
Здравствуйте, GuinPin, Вы писали:
GP>Не могу въехать, как правильно спроектировать класс. GP>В общем случае документ состоит из шапки, с несколькими обязательными атрибутами (идентификатор, позиция во времени, номер документа, автор и т.п.) и произвольным набором дополнительных атрибутов (клиент, склад, банк и т.п.) и произвольного количества табличных частей, содержащих произвольный набор атрибутов.
Может быть стоит начать рассматривать менее общий случай?
F>Предыдущий ответ "ни в бровь, а в глаз"
S>>Martin Fowler — Patterns of Enterprise Application Architecture
F>очень полезна и как раз рассматривает эти вопросы
Ну, заинтриговали прям
Почитаю.
Однако, если кто-то сможет поделиться практическим опытом, тоже будет неплохо
Здравствуйте, GuinPin, Вы писали:
GP>Не могу въехать, как правильно спроектировать класс. GP>В общем случае документ состоит из шапки, с несколькими обязательными атрибутами (идентификатор, позиция во времени, номер документа, автор и т.п.) и произвольным набором дополнительных атрибутов (клиент, склад, банк и т.п.) и произвольного количества табличных частей, содержащих произвольный набор атрибутов. GP>Собственно атрибуты могут быть как базовыми типами (число, строка и т.п.), так и ссылочными (клиент — ссылка на справочник клиентов). GP>Естественно, хочется абстрагироваться от непосредственной работы с БД, т.е. создать класс, реализующий модель документа. GP>Первый вопрос, с которым я столкнулся, это вариант создать базовый класс документа, которому наследовать реализацию конкретного вида документа. Либо создать универсальный класс документа, который будет получать метаданные о том виде документа, с которым ему предстоит работать. GP>Минусы первого варинта — большое количество наследников, в которых будут похожие механизмы работы с БД, т.е. появление практически дублирующегося кода. GP>Минусы второго — непонятно, как в общий универсальный документ засунуть бизнес-логику, уникальную для каждого конкретного вида документов. GP>Технически пока не совсем четко представляю: GP>разруливание ссылочных атрибутов GP>ссылка в документе-объект-отображение; GP>организацию работы с метаданными. GP>Вообще, сумбурчик пока что... GP>Буду благодарен за любую инвормацию по данной теме.
Опиши задачу конкретнее, тогда можно будет посмтореть...
Здравствуйте, AndreyFedotov, Вы писали:
AF> Опиши задачу конкретнее, тогда можно будет посмтореть...
Давай тогда на примере.
Накладную видел? Или счет, например.
Есть шапка (кому, от кого, дата, номер и т.п.)
Есть табличные части которых может быть от 0 до любого количества.
Данные документа хранятся в БД. Одна таблица на шапку и по одной на каждую табличную часть.
Атрибуты документа могут быть как базовыми типами (дата, количество, сумма) так и агрегатными (покупатель — ссылка на справочник покупателя и в таблице шапки документа в БД хранится только ссылка, хотя в документе может потребоваться любая информация о покупателе — наименование, адрес, счет..)
В принципе, все документы сходны, отличаются только наборами полей и бизнес-логикой.
Вот и требуется сообразить класс или набор классов, описывающих модель документа.
Можно конечно каждый документ ручками запрограммировать, однако хотелось бы более универсального решения. Т.е. документ при получении данных из БД видит, что эта циферька не циферька, а ID клиента, создает объект "Клиент" и заполняет его данными из справочника клиентов. Причем заметь, что допустим банк клиента — это тоже ссылка на справочник банков, поэтому объект "Клиент" тоже должент это понять и создать объект "Банк" и загрузить информацию о банке из соответствующей таблицы БД.
В итоге по концовке загрузки документа у меня должна быть гроздь объектов, инициализированных автоматом.
Примерно так.
Т.е. необходимо как-то организовывать работу с метаданными.
В общем, смутно пока это все
Здравствуйте, GuinPin, Вы писали:
GP>Здравствуйте, AndreyFedotov, Вы писали:
AF>> Опиши задачу конкретнее, тогда можно будет посмтореть...
GP>Давай тогда на примере. GP>Накладную видел? Или счет, например. GP>Есть шапка (кому, от кого, дата, номер и т.п.) GP>Есть табличные части которых может быть от 0 до любого количества. GP>Данные документа хранятся в БД. Одна таблица на шапку и по одной на каждую табличную часть. GP>Атрибуты документа могут быть как базовыми типами (дата, количество, сумма) так и агрегатными (покупатель — ссылка на справочник покупателя и в таблице шапки документа в БД хранится только ссылка, хотя в документе может потребоваться любая информация о покупателе — наименование, адрес, счет..) GP>В принципе, все документы сходны, отличаются только наборами полей и бизнес-логикой. GP>Вот и требуется сообразить класс или набор классов, описывающих модель документа. GP>Можно конечно каждый документ ручками запрограммировать, однако хотелось бы более универсального решения. Т.е. документ при получении данных из БД видит, что эта циферька не циферька, а ID клиента, создает объект "Клиент" и заполняет его данными из справочника клиентов. Причем заметь, что допустим банк клиента — это тоже ссылка на справочник банков, поэтому объект "Клиент" тоже должент это понять и создать объект "Банк" и загрузить информацию о банке из соответствующей таблицы БД. GP>В итоге по концовке загрузки документа у меня должна быть гроздь объектов, инициализированных автоматом. GP>Примерно так. GP>Т.е. необходимо как-то организовывать работу с метаданными. GP>В общем, смутно пока это все
Уже яснее... Тогда танцевать надо не от документа, а от предметной области, понятия которой хораняться в БД и в документе. Более того — "логика" — будет оперировать как раз понятиями (и классами) предметной области.
То есть — начинаешь с того, что строишь модель предментой области — того, чем вообще должна заниматься твоя система. Про бухгалтерию или документооборот написано много всего, в том числе описаны и основные понятия, которые там используются и взаимодействие между ними. Затем для этой модели предметной области строишь модель проектирования — т.е. конструируешь классы — для клиента, заказа, проводки и т.д. Для этих классов проектируешь механизмы сохранения и восстановления в/из БД и/или документа.
Кроме того, проектируешь классы представлений — для отображения и печати отдельных частей документа (объектов предментой области) — например представление шапки документа. Или же идёшь другим путём — пусть у тебя есть только классы предметной области, тогда ты можешь формировать визаульное представление документа с помощью системы генерации отчётов или XML/XSL=>HTML или RTF — с помошью конфигурируемых шаблонов.
Здравствуйте, hrg, Вы писали:
hrg>GuinPin -> "Класс документа" :
G>> Вообще, сумбурчик пока что... G>> Буду благодарен за любую инвормацию по данной теме.
hrg>Оффтопик. А оно надо — такой универсализм? Anatolix недано ссылку кидал на hrg>рассказ про универсальные движки. imho из той же области.
hrg>Нада начать с потребностей. Описать, какие документы буду выводиться. Начать hrg>с одного.
А как же не надо.
Ну представь, что в шапку документа добавились несколько полей.
На универсальном движке мне необходимо только подправить метаданные, внести изменения в бизнес-логику и формирование печатных форм. А работа с БД, представление объектов отработаются автоматом. А это не такой маленький кусок работы.
К тому же, механизмы работы с БД одинаковы — зачем плодить дублирующийся код? А если бага или фичу добавить? Ползать по реализациям десятка-другого документов и править ручками?
GuinPin -> "Re[2]: Класс документа" :
G>>> Вообще, сумбурчик пока что... G>>> Буду благодарен за любую инвормацию по данной теме.
hrg>> Оффтопик. А оно надо — такой универсализм? Anatolix недано ссылку hrg>> кидал на рассказ про универсальные движки. imho из той же области.
hrg>> Нада начать с потребностей. Описать, какие документы буду hrg>> выводиться. Начать с одного.
G> А как же не надо. G> Ну представь, что в шапку документа добавились несколько полей.
А представь, что это не надо
G> На универсальном движке мне необходимо только подправить метаданные, G> внести изменения в бизнес-логику и формирование печатных форм. А G> работа с БД, представление объектов отработаются автоматом. А это не G> такой маленький кусок работы.
А сколько типов документов у тебя есть? Сколько времени для написания отчета
для этого документа? Сколько по времени ты будешь писать этот движок?
Посчитай и сравни. Может и будет смысл писать движок. А может нет.
G> К тому же, механизмы работы с БД одинаковы — зачем плодить G> дублирующийся код? А если бага или фичу добавить? Ползать по G> реализациям десятка-другого документов и править ручками?
АК>Для справки скажу, что создание такого полноценного движка на .NET занимает порядка 30 человеко-месяцев.
Вопрос туманный, "полноценность" трудноопределима. С тем же успехом я могу сказать, что эта задача занимает 6 человеко-месяцев. Просто потому что нечто подобное делал. Возможно, это было в пять раз менее функционально, чем нужно, но вот так безапелляционно утверждать, что не меньше 30...
Если пока что сумбурчик, то реализуй пару-тройку разных документов напрямую, а потом уже станет видно, какие там интерфейсы кому нужны, какая функциональность общая и т.п. При написании в текущих условиях движка получиться то же самое (т.е. потом станет ясно, как надо), только больнее...
PS: Недаром в UML наследование называется генерализацией — этот термин точно отражает не только отношение типов, но и процесс, в результате которого это отношение возникает. При таком подхоже шанс получить крокодило-медведя (или прямоугольнуй круг) стремится к нулю.
можно создать класс с основными методами : чтение, вставка, обновление, удаление.
паблик поля(соответствуещего типа) этого класса будут отображать информацию из БД.
Если это документ, то соответсвенно это не одна таблица,
тогда в методе для чтения документа происходит выборка данных
перекресным запросом. Потом в соответсвующие поля заносится информация.
При сохранении проверяется валидность информации, подготовленной к сохранению. Если все ок,
тогда WriteToDB.
Этот подход позволяет, также, с наименьшими потерями поменять сервер БД при необходимости.
"GuinPin" <30228@news.rsdn.ru> сообщил/сообщила в новостях следующее: news:682666@news.rsdn.ru...
From: GuinPin
Не могу въехать, как правильно спроектировать класс.
Здравствуйте, Igor Trofimov, Вы писали:
>>Возможно, это было в пять раз менее функционально, чем нужно, но вот так безапелляционно утверждать, что не меньше 30...
Очевидно, конечно, что всё в сравнении. Но, насколько я понимаю, речь идёт как минимум о разработке какого-то фреймворка: некоторых базовых классов для поддержки сущностей, поддержки их отношений (наследование, агрегирование как строки документов, мастеровые отношения между объёктами), а также автоматическом их сохранении/чтении из источников данных + какой-то хотя бы настольный интерфейс для редактирования сущностей пользователями. Даже тут, на самом деле, вокруг, можно много чего навернуть для удобства программиста и пользователя. Я не слишком утверждаю , просто привёл, сколько это делалось в моей конторе. Я к тому, что если человек будет делать это один, или очень небольшим коллективом, лучше делать сразу специализированное решение.
Здравствуйте, Ramzes14, Вы писали:
R>Я тоже ломаю голову над подобной задумкой R>можно обьединить усилия для решения R>задачи
Пока не вижу смысла переносить обсуждение в мыло, лучше расскажу здесь, до чего я докопал. Может кто-то подскажет что полезное
В данный момент у меня набросана достаточно простая реализация, которая пока меня устраивает. Более-менее отладить планирую к понедельнику, тогда могу поделиться кодом. Пишу на VB.
Что мне было нужно в первую очередь, это отвязаться от структуры БД и поиметь готовые объекты, а не ссылки на связанную таблицу. Т.е. обеспечить автоматическую выборку данных из БД и автоматическое же создание объектов.
Итак, класс iCDAC — обеспечивает общие методв доступа к данным.
#Region "Метаданные"
'тип объекта (документ, справочник, периодический)
'вид объекта (Накладная,счет,контрагеты,товары и т.п.)
'наименование таблицы в субд
'строка подключения к БД
#Region "Переменные свойств и свойства класса"
'представление данных — возвращает строковое представление объекта
Public Overridable ReadOnly Property Text() As String
'данные поля по имени — установить или прочитать значение поля по имени
Public Property Field(ByVal name As String) As Object
#Region "Процедуры и функции модуля"
'создание объекта — создает соответствующий объект, если согласно метаданным, поле представляет собой ссылку
Private Function CreateRef(ByVal id As String, ByVal type As String) As Object
'загрузка данных — обеспечивает построение запроса на основе метаданных, выборку из БД и заполнение полей данными
Public Sub Load()
Классы второго уровня, наследники iCDAC — iDoc, iRef и iHist содержат в конструкторе определение метаданных, обязательных для своего типа:
iDoc: ИД, Позицию, Номер, Автора. Плюс дополнительный метод LoadTable(name as string) для загрузки табличной части документа
iRef: ИД, Наименование
iHist: ИД, ИД источника, Вид источника, Позицию, Значение
Третий уровень классов, наследники предыдущих, реализуют уже конкретные виды документов с бизнес-логикой, формированием печатных форм и т.п.
Экранные формы строятся отдельно и просто используют классы документов и справочников.
Пока примерно так.
На тестах это уже заработало, хотя и собрано на данный момент "на соплях".
Мне нравится попытка решить данный вопрос непосредственно с помощью XML -технологий.
Т.е разработка всяких схем для документов, погружение их в базу итп.
Правда в таком случае требуется, как минимум, какая-нибудь XML-Enable DataBase ( Oracle с 9.2 подходит), + возникает много всяких дополнительных вопросов (и о скорости тоже ).
Вопрос1: кто-нибудь из читающих такое делал? Писали ведь, что похожее разрабатывалось 30\9 человеко-месяцев на дотнете
Вопрос2: можно ссылку Anatolix-а про универсальные движки?
Если я правильно понял то ты и справочники и документы
хочеш хранить в одном классе
если так то тода не пойдет.
Это как говорится мухи отдельно г.. отдельно
я строю отдельно класс документа
который отвечает за обновление,извлечение,вставку и удаление данных из БД
таблица для хранения данных о шапках документов имеет такой вид(MySQL 4.1)
CREATE TABLE `docs` (
`GUID_Doc` int(11) NOT NULL default '0',
`GUID` int(11) NOT NULL default '0',
`GUID_Parent` int(11) NOT NULL default '0',
`GUID_Tip_Doc` smallint(2) NOT NULL default '2',
`GUID_Kontragent` int(11) NOT NULL default '0',
`GUID_Dost` int(11) NOT NULL default '0',
`Nomer` int(11) NOT NULL default '0',
`Nomer_Text` varchar(50) NOT NULL default '',
`FO` varchar(10) NOT NULL default '',
`Osnovanie` varchar(20) NOT NULL default '',
`Dover` varchar(200) NOT NULL default '',
`Data_Doc` date NOT NULL default '2003-10-01',
`Sum_Doc` double(8,2) NOT NULL default '0.00',
`Dolg` smallint(1) NOT NULL default '0',
`Dox` smallint(1) NOT NULL default '0',
`NDS_TIP` smallint(1) NOT NULL default '0',
`NDS_Sum` double(8,2) NOT NULL default '0.00',
`Prim` varchar(200) NOT NULL default '',
`Proved` smallint(1) NOT NULL default '0',
`Printed` smallint(1) NOT NULL default '0',
`Deleted` smallint(1) NOT NULL default '0',
`GUID_Creater` int(11) NOT NULL default '0',
`Data_Create` datetime NOT NULL default '0000-00-00 00:00:00',
`GUID_Changer` int(11) unsigned NOT NULL default '0',
`Data_Change` datetime NOT NULL default '0000-00-00 00:00:00',
`isNew` char(1) NOT NULL default '0',
PRIMARY KEY (`GUID_Doc`),
KEY `GUID_Tip_Doc` (`GUID_Tip_Doc`),
KEY `GUID_Kontragent` (`GUID_Kontragent`),
KEY `GUID_Dost` (`GUID_Dost`),
KEY `Nomer` (`Nomer`),
KEY `GUID_Parent` (`GUID_Parent`)
) TYPE=MyISAM CHARSET=latin1 COMMENT='данные о шапках документов';
ну или почти такой
Соответственно класс cDoc имеет такую же структуру как и TABLE `docs`
добавляются методы:
Insert()
Update()
Delete()
GetDan()
После этого уже строятся классы наследники
cRN,cPN,cPP и так далее каждый из которых
имеет уже свои вставки бизнес логики добавление
каких либо вычисляемых полей, полей содержащих
другие классы и т.д.
На основании этих классов уже можно строить коллекции
документов и т.д.
Это моё видение этой проблемы ну а уж тебе решать что и как