"Нехорошее это слово!" - считают некоторые, и не предпринимают никаких действий. "Нехорошая эта тенденция!" - считают другие и устраивают акции, потасовки и прочие нехорошие действия, сами, порой, не зная против кого... Ну, а что скажете по этому поводу вы, дрессировщики Лисы? По моему скромному убеждению, глобализация, это совсем не плохо, если вести речь об объекто-ориентированном программировании. Вернее не о всем ООП, а только его основе - объектах. Глобальные smart-объекты - это хорошо или плохо?
Начнем с родителя объекта - класса. Три кита ООП - они же три базовых принципа - инкапсюляция, наследование и полиморфизм.
Напомню кратенько, что эти три концепиции означают
Инкапсюляция - представляет собой концепцию "черного ящика". При использовании объекта у вас нет необходимости понимать его внутреннюю работу, или другими словами - как он работает. Объект должен предоставить вам всю необходимую информацию для взаимодействия с ним, или иными словами имеющийся у него набор свойств и методов. Предположим, к примеру, что у вас имеется объект, который получает строку, и возвращает число слов, ее составляющих. Вам нет необходимости знать, какие функции используются для подсчета слов в строке, вам важно знать только то, что вы вызовите метод GetWordsCount, передадите ему строку и получите в ответ число слов.
Наследование - представляет собой концепцию повторного использования. Класс представляет собой описание объекта, который может быть создан с помощью специальных функций, типа "СreateObject" или "NewObject", которым вы указываете из какого класса создать объект. Базовый класс в VFP представляет собой суперкласс, из которого могут быть созданы новые классы или субклассы.
Если мы создаем новый класс из базового класса, он наследует все его свойства и методы, за исключением одного - имени. Вы не можете описать субкласс, один к одному, с тем же именем, что и базовый или суперкласс. Вы можете переписать значения его свойств или процедурный код в методах субкласса, добавить свои пользовательские свойства и методы. Затем вы на основе этого субкласса можете создать новый субкласс, который унаследует неизмененные свойства базового суперкласса, а также все изменения, которые вы произвели при создании субкласса первого уровня.
Полиморфизм - самая сложная в понимании концепция, как выяснилось из общения на форумах. Сущность этой концепции заключается в том, что класс должен обрабатывать различные типы данных, с тем, чтобы у вас не было необходимости писать для каждого типа данных свой собственный класс. Самый классический пример - класс рисования контуров, который может рисовать круги, прямоугольники или эллипсы. Класс должен иметь соответствующие методы, для создания соответствующего контура, которые будут вызваны классом, а не вами, и которые создадут требуемый контур на основе переданного объекту класса списка параметров.
Ну а теперь, вернемся в нашему барану - глобальному smart-объекту. И рассмотрим очень простой его вариант.
Представим себе фирму, продающей компьютеры своей сборки. В эту фирму пришел покупатель с желанием приобрести компьютер за 8000 крон. В фирме, имеющей установленную 1С, продавец создаст новый инвойс или предложение и начнет носиться по дереву каталогов, подбирая компоненты и меняя их, время от времени, с целью обеспечения желаемой пользователем цены. Даже великий спец потратит на это немало времени. (Я сам часто являюсь покупателем и знаю, что на оформление заказа уходит минимум - 10 минут.) А что если вы просто напечаете команду Do constructor with "computer","8000EEK"? Что может произойти в результате? Мой командный файл, обеспечивающий такую функциональность выглядит так:
LPARAMETERS lpcGlobalClass,lpuAttribute
LOCAL loGObject
loGObject=CREATEOBJECT(lpcGlobalClass,lpuAttribute)
loGObject.ShowMe()
Давайте составим описание компьютера. Из чего состоит физический объект "компьютер"?
- Материнская плата
- Процессор
- Память
- Жесткий диск
- Видеокарта (может быть встроенной в "маму")
- CD-Rom
- Корпус
- Блок питания (может поставляться вместе с корпусом)
Приведенный список можно охарактеризовать выражением "must have". То есть, включает в себя минимально необходимую конфигурацию, после обретения которой железный ящик может обрести жизнь. Поскольку есть список "must have", то напрашивается список "may have". Что может содержать такой список.
- Сетевая карта(может быть встроенной в "маму")
- Звуковая карта (может быть встроенной в маму)
- Флоппи-диск
- DVD-Rom
- Беспроводная сетевая карта
- Считыватель медиа-карт
Разумеется, здесь упрощение, с целью облегчения понимания смысла. Возможен и третий список "should be have", который может содержать вариации первого и второго списка. Например - CD-ROM может быть пищущим, а может быть и комбинированным устройством - чтение DVD/чтение+запись CD.
Если еще раз взглянуть на текст программы, то команда loGObject.ShowMe() подразумевает по смыслу ее имени какой-то интерфейс. Однако сразу должен оговориться, что глобальный объект не предсталяет собой объект формы или прочего визуального класса, который будет помещен на форму. Отнюдь. Глобальный объект создается на базе невизуального класса - Custom, и при необходимости создаст интерфейс сам.
Что необходимо этому глобальному объекту для успешной работы? Описание структуры будущего объекта, вроде той, что приведена выше и складские таблицы.
Как описать структуру? Разумеется парами - параметр:значение. Тогда, например, слегка упрощенная структура комьютера могла бы выглядеть так.
computer {
motherboard:mustHave;
processor:mustHave;
memory:mustHave;
harddisk:mustHave;
videocard:mustHave;
cdrom:mustHave;
case:mustHave;
powersupply:mustHave;
networkcard:mayHave;
soundcard:mayHave;
floppydrive:mayHave;
wifinetworkcard:mayHave;
mediacardreader:mayHave;
}
Что должен сделать глобальный smart-класс?
- Во-первых, найти описание структуры требуемого объекта (в нашем случае это "компьютер") в таблице описания структур.
- Во-вторых, по именам параметров найти в таблице описаний базы данных складские таблицы (таблицу), содержащие информацию о компонентах компьютера.
- В третьих, определить смысл параметра "8000EEK". В качестве второго параметра, например, может быть предпочтение - Intel/AMD, или марка брэнда или даже просто "multimedia".
- В-четвертых, составить варианты конфигураций в виде объектов конфигураций, на основе складских данных с первичным допуском +/- 10% от запрашиваемой цены, для нашего рассматриваемого случая.
- В-пятых, обозначить имена конфигураций и вывести их в список, при прохождении которого необходимо будет вывести параметры каждой конфигурации, то есть создать интерфейс применительно к этой задаче.
- В-шестых, интерфейс предусматрвает создание инвойса по сформированной конфигурации и его печать. Кроме того, в интерфейсе будут созданы объекты с аттрибутом AskUser, которые могут быть оформлены в виде комбинаций чек-боксов с комбобоксами (или со списками, или с радиокнопками - в зависимости от числа возможных вариантов), с целью обработки списков "may have" и "should be have".
В итоге, будет получена форма, на которой будет первой предложена конфигурация, наиболее близко соответствующая запрашиваемой цене, а если такой конфигурации не удасться составить, то будет предложен ближайший вариант. При подтверждении покупателем конфигурации, класс сгенерирует и отпечает инвойс или предложение. Разработанный класс выполнил всю работу менее, чем за минуту, причем основное время было потрачено на подтверждение конфигурации - перемещение мышки к кнопке "Accept" и щелчок по ней.
Глобальный smart-класс соответствует всем требованиям ООП. Во-первых, это реальный "черный ящик". Во вторых, создаваемый им объект компьютера наследует структуру, описанную для этого типа. В третьих, класс обладает полиморфизмом, так как обрабатываемые данные различаются по типу и определяются описанной структурой.
А что, если описание требуемого объекта отсутствует? В глобальном классе предусмотрен метод AskStructure(), который будет формировать вопросы пользователю и на основании его ответов формировать структуру. Задачка, кажущаяся, на первый взгляд, достаточно сложной на самом деле решается достаточно просто и позволяет вам создавать весьма сложные приложения, потратив при этом минимум времени. Работа с глобальным объектов показано в демо-файле. Для отображения демо-файла в браузере требуется наличие установленного проигрывателя flash-файлов.
Я думаю, что глобализация - удачный термин, да и "usability" здесь идет с ним рука об руку.
Если идея понятна, то вперед и с песней "Мы рождены, что сказку сделать былью"!
|