Войти
 
 
   
 
  
Новости Notes.ру Библиотека Биржа труда Вопрос - ответ Форум Регистрация Поиск О проекте
Разделы
О Notes
Советы
Шаблоны и примеры
Литература
Презентации
 
Java: внутри файла MS Excel 2007. Часть четвёртая   В публикуемой сегодня части статьи заканчивается описание процедур загрузки электронной таблицы и начинается описание самого интересного - каким образом получить данные, хранящиеся в ячейках таблицы
Шаблоны и примеры Читать статью
 
Java: внутри файла MS Excel 2007. Часть третья   В предлагаемой вниманию читателя третьей части статьи о структуре файла электронной таблицы Microsoft Excel формата 2007 речь идёт о коде Java, "разархивирующем" файловый поток и формирующем объекты, с которыми предстоит взаимодействовать при дальнейшей обработке данных электронной таблицы
Шаблоны и примеры Читать статью
 
Java: внутри файла MS Excel 2007. Часть вторая   В настоящем материале автор постарается систематизировать свои знания о том, как устроено хранение данных электронной таблицы, и презентовать небольшую Java-библиотеку, предоставляющую возможность чтения данных и заполнения файла электронной таблицы Microsoft Excel
Шаблоны и примеры Читать статью
 


Шаблоны и примеры

Главная   Библиотека   Шаблоны и примеры

Паттерны. Часть 2. Фасад для абстрактного документа

Часть 1. Фасад >>>
Часть 2. Фасад для абстрактного документа
Часть 3. Фасад для документа >>>
Часть 4. Итератор >>>
Часть 5. Factory >>>

Денис Самойлович
В продолжение темы "Паттерны. Часть 1. Фасад" (>>>) предположим, что мы решили-таки заворачивать документы в классы. С чего начать? Есть, наверное, смысл создать фасад для абстрактного документа. Класс, который будет реализовывать некие общие принципы обработки документа.
CLASS DOCUMENT
Вот описание класса и базовый набор свойств. Дополнительных комментариев здесь я думаю не требуется.
Public Class Document As Something
meDoc As NotesDocument
Sub New(sourceDoc As NotesDocument), Something()
Set meDoc = sourceDoc
End Sub ' New
Property Get Form As String
Form = meDoc.GetItemValue("Form")(0)
End Property ' Get Form
Property Get UNID As String
UNID = meDoc.UniversalID
End Property ' Get UNID
Property Get Document As NotesDocument
Set Document = meDoc
End Property ' Get Document
Property Set Document As NotesDocument
Set meDoc = Document
End Property ' Set Document
End Class ' Document
READERS, AUTHORS, SUBJECT, CATEGORY
Каждый документ потенциально может иметь стандартные поля, которые нам хотелось бы единобезобразно (в рамках приложения) обрабатывать. Это, во-первых, поля, регулирующие доступ. Плюс поля, имеющие в Lotus Notes общеупотребительное значение.
В общем случае не предполагается, что эти поля будут устанавливаться программно. Значения для этих полей, как правило, определяются где-то в другом месте. В форме, например. Или вычисляются автоматически в зависимости от каких-то условий.
Public Const FN_READERS = "DocReaders"
Public Const FN_AUTHORS = "DocAuthors"
Public Const FN_SUBJECT = "Subject"
Public Const FN_CATEGORY = "Category"
...
Public Class Document As Something
...
Property Get Readers As NotesItem
Set Readers = meDoc.GetFirstItem(FN_READERS)
End Property ' Get Readers
Property Get Authors As NotesItem
Set Authors = meDoc.GetFirstItem(FN_AUTHORS)
End Property ' Get Authors
Property Get Subject As String
Subject = meDoc.GetItemValue(FN_SUBJECT)(0)
End Property ' Get Subject
Property Get Category As String
Category = meDoc.GetItemValue(FN_CATEGORY)(0)
End Property ' Get Category
End Class ' Document
STATUS
Индикатор статуса присутствует в очень многих документах в Lotus Notes. Поэтому имеет смысл включить соответствующие свойство в наш абстрактный фасад.
Public Const FN_STATUS = "Status"
...
Public Class Document As Something
...
Property Get Status As String
Status = meDoc.GetItemValue(FN_STATUS)(0)
End Property ' Get Status
Property Set Status As String
Call meDoc.ReplaceItemValue(FN_STATUS, Status)
End Property ' Set Status
End Class ' Document
СОЗДАНИЕ, СОХРАНЕНИЕ, УДАЛЕНИЕ
1) Создаваться документ может как угодно. Но нам бы хотелось унифицировать этот процесс. Например, чтобы при создании автоматически инициализировались какие-то критические поля.
Для этого выделяем это действие в отдельный метод, который, вообще говоря, может быть перекрыт в классах-наследниках.
2) Сохранение документа можно сделать проще (убрав лишние параметры и добавив обработчик ошибок). Плюс хотелось бы при сохрании автоматически обновлять поля доступа и поля, содержащие описательную информацию о данном документе (как конкретно это делать, определяется в порождаемых классах).
3) Процесс удаления тоже хотелось бы унифицировать. Поскольку рекомендуется отключать у пользователей возможность физически удалять документы, то возникает необходимость в неком программном механизме удаления. Как это сделать - дело вкуса. Здесь представлен один из вариантов.
Public Const FN_SYS_CONFLICT = "$Conflict"
Public Const FN_SYS_REF = "$Ref"
Public Const ROLE_ADMIN = "[Admin]"
...
Public Class Document As Something
...
Sub Create(db As NotesDatabase)
Set meDoc = db.CreateDocument
Call meDoc.ReplaceItemValue("Form", Me.Form)
End Sub ' Create
Function Save As Integer
Save = Me.SaveAs(True)
End Function ' Save
Function SaveAs(force As Integer) As Integer
try:
On Error Goto catch
Call meUpdateAccessFields
Call meUpdateDescriptionFields
Call meDoc.ReplaceItemValue("Form", Me.Form)
SaveAs = meDoc.Save(force, False)
Exit Function
catch:
SaveAs = False
Resume finally
finally:
End Function ' SaveAs
Private Sub meUpdateAccessFields
End Sub ' meUpdateAccessFields
Private Sub meUpdateDescriptionFields
End Sub ' meUpdateDescriptionFields
Function Remove(force As Integer) As Integer
try:
On Error Goto catch
If force Then
Me.Remove = meDoc.Remove(True)
Else
Call meDoc.ReplaceItemValue("Form", Me.Form & "_removed")
Call meDoc.RemoveItem(FN_SYS_REF)
meDoc.ReplaceItemValue(FN_READERS, ROLE_ADMIN).IsReaders = True
meDoc.ReplaceItemValue(FN_AUTHORS, ROLE_ADMIN).IsAuthors = True
Me.Remove = meDoc.Save(True, False)
End If
Exit Function
catch:
Me.Remove = False
Resume finally
finally:
End Function ' Remove
End Class ' Document
РАБОТА С НЕСТАНДАРТНЫМИ ПОЛЯМИ
Хотелось бы добавить пару сервисных функций для обработки полей нестандартных типов.
Многозначные поля хотелось бы склеивать и расклеивать согласно какому-то разделителю. Дату/время хотелось бы получать в более удобном формате. Ну и про RT-поля нельзя забывать. Здесь полная свобода для творчества. Кому что нравится, то можно и добавлять.
Public Class Document As Something
...
Public Function GetItemValues(fieldName$, delimiter$) As String
GetItemValues = ""
Dim item As NotesItem
Set item = meDoc.GetFirstItem(fieldName$)
If item Is Nothing Then Exit Function
Dim result$
result$ = ""
Forall currValue In item.Values
result$ = StrConcat(result$, Cstr(currValue), delimiter$)
End Forall
GetItemValues = result$
End Function ' GetItemValues
Public Function ReplaceItemValues(fieldName$, values$, delimiter$) As NotesItem
Dim values1 As Variant
values1 = Split(values$, delimiter$)
Dim values2 As Variant
values2 = Fulltrim(values1)
Set ReplaceItemValues = meDoc.ReplaceItemValue(fieldName$, values2)
End Function ' ReplaceItemValues
Public Sub ReplaceRichText(fieldName$, rt As NotesRichTextItem)
Call meDoc.RemoveItem(fieldName$)
If Not rt Is Nothing Then
Call rt.CopyItemToDocument(meDoc, fieldName$)
End If
End Sub ' ReplaceRichText
Public Function GetDateValue(fieldName$) As NotesDateTime
Dim value As Variant
value = meDoc.GetItemValue(fieldName$)(0)
If Isdate(value) Then
Dim dt As New NotesDateTime("")
dt.LSLocalTime = value
Call dt.SetAnyTime
Set GetDateValue = dt
Else
Set GetDateValue = Nothing
End If
End Function ' GetDateValue
End Class ' Document
Часть 1. Фасад >>>
Часть 2. Фасад для абстрактного документа
Часть 3. Фасад для документа >>>
Часть 4. Итератор >>>
Часть 5. Factory >>>

Читайте на Notesnet.ru
О пользе ООП при проектировании систем на платформе Lotus Notes/Domino >>>
Пример UI элемента на основе паттерна MVC >>>
Использование паттерна MVC в модальных диалоговых окнах >>>
 
  Опубликовано — 08/28/2009 |    

Denny, 09.09.2009 20:24:08:
2VladSh: да, все это звучит немного странно. Достаточно много людей крутило пальцем у виска, пока сами не попробовали... Честно. Гнилой товар не продаем :)

P.S. не забывайте, в статье изложена лишь очень упрощенная концепция. На практике все гораздо приятнее.

VladSh, 09.09.2009 18:24:34:
Denny

Вопрос: а так ли нужно "отключать мозги"? :)
"Контроль типов" вылазит на этапе отладки-тестирования; в работающей системе он важен также как, например, наименование переменной) Грамотные обработчики ошибок - и всё. Для крупной группы разработчиков с невысоким уровнем возможно оправдано.
"Надёжность системы в целом" зависит от качества тестирования и документирования разработки) Всё IMHO конечно, но я считаю, что иначе это всё общие слова.

Такие классы узкоспециализированы. Интересно, но... не моё)

С уважением, Влад

Denny, 09.09.2009 11:21:33:
2VladSh: это часть концепции под условным названием программирование с отключенным мозгом. Следуя этой методике, мы возлагаем контроль типов на компилятор, повышаем уровень абстракции, защищенности и надежности системы в целом.

Создавать свойства для полей нужно по мере необходимости. Очевидно если какое-то поле никогда не меняется программно, то и SET для него не нужен.

VladSh, 03.09.2009 19:36:34:
Property Get Form As String
Property Get Subject As String
Property Get Category As String
...
Решение красивое, но не универсальное. IMHO накладно для работы с каждым полем плодить по 2 свойства (Get и Set).
2 метода класса GetItemValue и ReplaceItemValue, по моему, более элегантное решение, оно даёт возможность передавать в другие функции и классы либо собственный объект собственного класс либо объект класса NotesDocument - это очень удобно, т.к. в обоих классах методы есть - универсальная обработка.



Добавить комментарий
Имя * :
e-mail
Комментарий * :
Код подтверждения * :


Мероприятия
Пресс-релизы
Биржа труда
Последнее на форуме
 
А так же:
Lotus notes и ЭЦП
29.09.2017 17:16:14
Как удалить профиль?
16.04.2016 00:08:51
Скопировать в буфер поле документа
24.05.2015 08:55:52
 
© LOGOSPHERE.RU