
Итак, в первой части мы затронули применение UDT в обычном модуле, и в комментариях справедливо заметили, что UDT сильно проигрывает классам. И да, действительно, если использовать класс как DTO (Data Transfer Object), он более функционален, чем UDT.
В этой заключительной части, я хотел бы рассказать о применении UDT в классах, кто такой Mathieu Guindon и причем тут резиновая уточка.
Ключевое слово this
Ну, на самом деле я слегка лукавлю, такого кейворда в VBA нет, но обо всем по порядку.
Обозначим задачу:
Мы разобрали, как использовать UDT в качестве структуры письма (см. первую часть). Это вполне себе рабочая схема, но иной раз не совсем удобная.
В чем же минусы? Сходу я вижу как минимум два:
-
Нет возможности встроить проверку передаваемых значений.
-
Чтобы собрать несколько UDT в один контейнер, в качестве этого самого контейнера можно использовать только массив. Это не то, чтобы критично, но часто неудобно.
А по сему, попробуем сделать реализацию структуры TLetter в виде класса.
Создаем новый класс-модуль и называем его Letter. Сразу пропишем необходимые поля:
Option Explicit Public AddressTo As String Public AddressCC As String Public Subject As String
Так как это класс, надо бы пользоваться его функционалом.
Добавим проверку передаваемых значений, например email-адресов. Усложнять не будем, просто проверяем наличие символа «@» и бросаем ошибку, если его нет:
Option Explicit Private AddressTo1 As String Private AddressCC1 As String Private Subject1 As String Public Property Get AddressTo() As String AddressTo = AddressTo1 End Property Public Property Let AddressTo(ByVal RHS As String) If Not ValidateEmail(RHS) Then Err.Raise 0, TypeName(Me) AddressTo1 = RHS End Property Public Property Get AddressCC() As String AddressCC = AddressCC1 End Property Public Property Let AddressCC(ByVal RHS As String) If Not ValidateEmail(RHS) Then Err.Raise 0, TypeName(Me) AddressCC1 = RHS End Property Public Property Get Subject() As String Subject = Subject1 End Property Public Property Let Subject(ByVal RHS As String) Subject1 = RHS End Property Private Function ValidateEmail(ByVal Email As String) As Boolean ValidateEmail = InStr(1, RHS, "@") > 0 End Function
Что мы видим? Добавились свойства. У полей изменился модификатор доступа на private и к каждому имени добавилась цифра 1.
Проблема в том, что VBA не чувствителен к регистру имен переменных, поэтому addressTo и AddressTo для него одно и тоже, а соответственно свойства и поля называть одинаково мы не можем.
И вот тут как нельзя кстати будет UDT
Объявляем новый тип TLetter, помещаем в него все наши поля (с нормальными названиями, без цифр). Далее объявляем приватное поле this с типом TLetter.
Теперь переданное в свойство значение помещается в переменную вида this.AddressTo, что выглядит куда лучше и понятнее:
Option Explicit Private Type TLetter AddressTo As String AddressCC As String Subject As String End Type Private this As TLetter Public Property Get AddressTo() As String AddressTo = this.AddressTo End Property Public Property Let AddressTo(ByVal RHS As String) If Not ValidateEmail(RHS) Then Err.Raise 0, TypeName(Me) this.AddressTo = RHS End Property Public Property Get AddressCC() As String AddressCC = this.AddressCC End Property Public Property Let AddressCC(ByVal RHS As String) If Not ValidateEmail(RHS) Then Err.Raise 0, TypeName(Me) this.AddressCC = RHS End Property Public Property Get Subject() As String Subject = this.Subject End Property Public Property Let Subject(ByVal RHS As String) this.Subject = RHS End Property Private Function ValidateEmail(ByVal Email As String) As Boolean ValidateEmail = InStr(1, RHS, "@") > 0 End Function
Mathieu Guindon и Rubberduck
Я думаю, вы наверняка уже видели подобное такое решение в моей первой статье на Хабре. По сути такой подход — есть ни что иное как паттерн. Автор этого паттерна господин Mathieu Guindon, он же автор достаточно известного дополнения для VBE — Rubberduck (резиновая уточка).
Так как в этой статье мы все таки разбираем UDT и способ его применения, а не то почему так правильнее делать, я бы хотел передать слово самому Mathieu, а именно его статье Private this As TSomething. В ней он достаточно подробно разбирает почему это удобно и чем плоха Венгерская нотация (а именно, добавление в название поля m — mAddressTo).
Короче…
Эта часть вышла более компактной, т.к. цель данной статьи не переписывать слова автора паттерна, а скорее обратить внимание на такой подход.
Надеюсь, что тем не менее было полезно.
Спасибо, что прочитали до конца.
Стали бы применять подобный паттерн? Пишите в комментариях!
А также, подписывайтесь на мой телеграмм.
ссылка на оригинал статьи https://habr.com/ru/post/711222/
Добавить комментарий