Войти
 
 
   
 
  
Новости Notes.ру Библиотека Биржа труда Вопрос - ответ Форум Регистрация Поиск О проекте
Разделы
О Notes
Советы
Шаблоны и примеры
Литература
Презентации
 
Всё о задаче AdminP. Часть вторая   Во второй части мы завершаем рассмотрение AdminP. В ней рассмотрены запросы междоменного администрирования и способы управления функциями AdminP с помощью настроек документа сервера, команд консоли сервера, файла Notes.ini и интервалов очистки базы данных. В этой статье предполагается, что вы опытный администратор Domino и прочитали первую часть
О Notes Читать статью
 
Всё о задаче AdminP. Proxy-действия в R5 и Domino 6   Приложение к статье об административном процессе
О Notes Читать статью
 
Всё о задаче AdminP. Часть первая   Перевод классической статьи 2003-его года о задаче административного процесса (AdminP). Очень полезна для понимания работы механизма этой задачи. В первой части статьи описаны компоненты задачи AdminP, как они работают, и как их использование помогает сделать работу администратора Domino проще. Задача AdminP (сакращённо от Administration Process, Административный процесс) работает с базой административных запросов (Administration Requests, admin4.nsf)
О Notes Читать статью
 


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

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

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

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

Денис Самойлович
Предположим, у нас есть форма-опросник, по которой один человек (Reviewer) дает свою оценку деятельности другого человека (Evaluee). Форма содержит список вопросов, ответы на которые заранее определены, например:
Completely agree|7
Strongly agree|6
Somewhat agree|5
Neither agree nor disagree|4
Somewhat disagree|3
Strongly disagree|2
Completely disagree|1
Insufficient exposure|NA
Нам нужно организовать фасад для документов, которые содержат эти вопросы.
КЛАСС SURVEY
начнем с создания нового класса:
Option Declare
Use "document.class"
Public Const FORM_SURVEY = "survey"
Public Class Survey As Document
'
Sub New(sourceDoc As NotesDocument), Document(sourceDoc)
'
End Sub ' New
Property Get Form As String
' overwritten
Form = FORM_SURVEY
End Property ' Get Form
End Class ' Survey
Заметьте, что первым делом мы определили константу FORM_SURVEY и переопределили метод Survey.Form. Теперь документы созданные через фасад всегда будут иметь правильную форму.
ПРИНАДЛЕЖНОСТЬ
теперь нужно задать набор свойств, определяющих на кого заведена эта форма и кто на нее отвечал
...
Private Const FN_EVALUEE_NAME = "EvalueeName"
Private Const FN_EVALUEE_ADDRESS = "EvalueeAddress"
Private Const FN_REVIEWER_NAME = "ReviewerName"
Private Const FN_REVIEWER_ADDRESS = "ReviewerAddress"
Public Class Survey As Document
...
Property Get EvalueeAddress As String
'
EvalueeAddress = meDoc.GetItemValue(FN_EVALUEE_ADDRESS)(0)
End Property ' Get EvalueeAddress
Property Set EvalueeAddress As String
'
meDoc.ReplaceItemValue(FN_EVALUEE_ADDRESS, CanonicalName(EvalueeAddress)).IsNames = True
Call meDoc.ReplaceItemValue(FN_EVALUEE_NAME, CommonName(EvalueeAddress))
End Property ' Set EvalueeAddress
Property Get EvalueeName As String
'
EvalueeName = meDoc.GetItemValue(FN_EVALUEE_NAME)(0)
End Property ' Get EvalueeName
Property Get ReviewerAddress As String
' SML
'
ReviewerAddress = meDoc.GetItemValue(FN_REVIEWER_ADDRESS)(0)
End Property ' Get ReviewerAddress
Property Set ReviewerAddress As String
' SML
'
meDoc.ReplaceItemValue(FN_REVIEWER_ADDRESS, CanonicalName(ReviewerAddress)).IsNames = True
Call meDoc.ReplaceItemValue(FN_REVIEWER_NAME, CommonName(ReviewerAddress))
End Property ' Set ReviewerAddress
Property Get ReviewerName As String
' SML
'
ReviewerName = meDoc.GetItemValue(FN_REVIEWER_NAME)(0)
End Property ' Get ReviewerName
End Class ' Survey
Какие бенефиты мы имеем с этих свойств?
- имена всегда определяются в правильном формате независимо от того какую строку мы передали в свойство SET (функции CanonicalName и CommonName определены где-то в другом месте и возвращают имя в соответствующем формате).
- поскольку ReviewerName всегда вычисляется из ReviewerAddress, то мы не определяем SET для него и тем самым защищаем это поле от неправильного использования (то же для EvalueeName и EvalueeAddress).
- зачем вообще нужны EvalueeName/ReviewerName? Не проще ли всегда использовать EvalueeAddress/ReviewerAddress? Здесь они введены, главным образом, с целью показать варианты использования этой технологии. Хотя практическая польза тоже есть. Потенциально мы не властны над содержимым NAMES полей. Сервер может поменять имя, а то и удалить его. Чтоб при этом не терялась привязка документа к конкретному человеку, его имя можно хранить в текстовом поле.
ОТВЕТЫ
Настала пора написать функциональность получения ответов из документа. Допустим, все вопросы поделены на N блоков по M вопросов в каждом блоке. В какой форме хранятся ответы на каждый вопрос - для нас неважно. Может быть, в едином XML-подобном формате в одном единственном поле. Может быть, в многозначных полях. Может, каждому ответу соответствует одно поле. Наша задача абстрагировать того, кто будет использовать наш класс, от этих утомительных подробностей.
...
Public Class Survey As Document
'
...
Function GetAnswer(blockIndex As Integer, questionIndex As Integer) As String
'
End Function ' GetAnswer
End Class ' Survey
WORKFLOW
методы получения и установки текущего состояния документа наследуются из родительского класса. Нам осталось только определить набор констант состояний.
...
Public Const STATUS_SURVEY_DRAFT = "Draft"
Public Const STATUS_SURVEY_NOTIFIED = "Notified"
Public Const STATUS_SURVEY_REMINDED = "Reminded"
Public Const STATUS_SURVEY_SUBMITTED = "Submitted"
Public Const STATUS_SURVEY_CLOSED = "Closed"
...
ПРАВА ДОСТУПА
при каждом сохранении документа в зависимости от статуса (или каких других критериев) должны перевычисляться Readers/Authors поля. Из родительского класа нужно взять метод meUpdateAccessFields и переопределить его. И все. С этого момента голова у того, кто использует наш класс, болеть не должна (он меняет статус и сохраняет документ, все остальное вычисляется автоматически).
...
Private Const FORMULA_AUTHORS = |
tmpNames := @If(Status = "Draft":"Notified":"Reminded"; ReviewerAddress; "");
tmpNames := @Unique(@Left(@Name([Abbreviate]; tmpNames) + "@"; "@"));
@Trim("[Admin]" : @Name([Canonicalize]; tmpNames))
|
Private Const FORMULA_READERS = |
tmpNames := ReviewerAddress;
tmpNames := @Unique(@Left(@Name([Abbreviate]; tmpNames) + "@"; "@"));
@Trim("[Admin]" : @Name([Canonicalize]; tmpNames))
|
Public Class Survey As Document
Private Sub meUpdateAccessFields
' overwritten
'
Dim names As Variant
names = Evaluate(FORMULA_AUTHORS, meDoc)
meDoc.ReplaceItemValue(FN_AUTHORS, names).IsAuthors = True
names = Evaluate(FORMULA_READERS, meDoc)
meDoc.ReplaceItemValue(FN_READERS, names).IsReaders = True
End Sub ' meUpdateAccessFields
End Class ' Survey
Здесь используется немного странная концепция вычисления Readers/Authors полей. Через Evaluate. Я очень редко использую Evaluate (смешение технологий дает не только сумму преимуществ, но иногда и произведение недостатков). Но здесь пришлось пойти на уступки.
Дело в том, что в оригинальной UI-форме есть вычисляемые поля Readers/Authors с такими же формулами. Поэтому, чтоб не потерять ни капли оригинальной логики, формула переносится как есть в LotusScript. Здесь это не правило, а просто один из вариантов реализации.
ИСПОЛЬЗОВАНИЕ
теперь можно переходить к возможным вариантам использования. Например, создание нового документа может выглядеть так:
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase
Dim survey As New Survey(db.CreateDocument)
survey.EvalueeAddress = "Denis
Samoylovich/NYC/NorthAmerica/MCKINSEY-EXTERNAL"
survey.ReviewerAddress = "Denis Samoylovich/Germany/IBM"
survey.Status = STATUS_SURVEY_DRAFT
Call survey.Save()
' или "закрытие" выделенных документов:
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase
Dim docs As NotesDocumentCollection
Set docs = db.UnprocessedDocuments
Dim currSurvey As New Survey(docs.GetFirstDocument)
While Not currSurvey.Document Is Nothing
currSurvey.Status = STATUS_SURVEY_CLOSED
Print currSurvey.EvalueeName + " / " currSurvey.ReviewerName
Call currSurvey.Save()
Set currSurvey.Document = docs.GetNextDocument(currSurvey.Document)
Wend

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

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



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


Мероприятия
Пресс-релизы
Биржа труда
Последнее на форуме
 
А так же:
Как удалить профиль?
16.04.2016 00:08:51
Скопировать в буфер поле документа
24.05.2015 08:55:52
Импорт DXL-описания документов в Lotus Domino. Одноимённые поля
16.04.2015 16:49:58
 
© LOGOSPHERE.RU