2. Структурное программирование и объектная парадигма .
Рассмотрим задачу – изменить значение поля FIELD1 ( новое значение – “Привет”) таблицы TABLE1 у записи с № 10.
Решение (структурное программирование XBase++):
1 DbSelect(0)
2 DbUse(“TABLE1”)
3 DbGoTo(10)
4 DbRLock()
5 DbPutField(“FIELD1”,”Привет”)
6 DbRUnlock()
7 DbCloseArea()
Решение 2: (структурное программирование XBase++)
1 Local cAlias := Alias()
2 DbUse(“TABLE1” , cAlias)
3 (cAlias )->(DbGoTo(10))
4 (cAlias )->(DbRLock())
5 (cAlias )->(DbPutField(“FIELD1”,”Привет”))
6 (cAlias )->(DbRUnlock())
7 (cAlias )->(DbCloseArea())
Решение 3: ( классовый подход БЭСТ5)
1 Local x := new DbTable(“Table1”)
2 x:Goto(10)
3 x:PutField(“Field1”,”Привет”)
4 x:Close()
Объектная парадигма, а затем и целая плеяда ОО Языков, реализующих ее, возникли не случайно. “Все что существует – необходимо” (Гегель). Наследование, инкапсуляция, полиморфизм – вот основные идеи ООП. Какие задачи призваны решать эти идеи. Когда Ваш проект состоит из сотен строк кода, то я думаю принципиальной разницы между структурным программированием и ООП – нет. А вот когда проект разрабатывает бригада, состоящая из нескольких десятков разработчиков – проект “стремится” выйти из под контроля, структурные подходы значительно проигрывают.
Инкапсуляция.
Основное назначение инкапсуляции – сокращение числа ошибок и периода тестирования. Если не играться в дефиниции, то инкапсуляцию можно определить как способ объединения данных и методов, обрабатывающих эти данные в одном месте (классе). В нашем примере (3) метод PutField класса DbTable реализует блокировку таблицы, модификацию данных и снятие блокировки. Использование класса дает нам не столько сокращение числа строк в проекте, сколько избавляет нас от человеческой забывчивости (обычно – забывают не только блокировать, но и снимать блокировки). Думаю, вполне очевидно, что когда речь идет о сотнях тысяч строк кода выигрыш будет весьма ощутим. Инкапсуляция, как впрочем ООП в целом призвана скрыть от пользователя (программиста, использующего класс) тонкости реализации.
Пример из жизни. В процессе использование класса DbTable прикладные программисты (пользователи класса DbTable) предложили реализовать возможность использовать SQL SEL ECT предложения. Они хотели писать примерно так:
Local x := CreateDbTable( ;
“SEL ECT Code,Left(Name,20) AS NAME FR OM TABLE1 WHERE NAME LIKE “%ПРИВЕТ%”);
Сейчас так можно писать в БЭСТ5. Вся дальнейшая работа с экземплярами (объектами) класса DbTable не изменилась. x:PutField(“FIELD1”,”Привет”) .
Более того, можно писать и так x:Field1 := “Привет”. Но это уже нюансы.
Полиморфизм.
Рассматривать идею полиморфизма в не строго типизированных языках нет смысла, поэтому мы пропустим этот
. Если будет особая необходимость рассмотрим дополнительно.
Наследование.
Наиболее прозрачная
. Класс MetaBO наследуется от класса DbTable и инкапсулирует DbTable. Но если класс DbTable призван реализовать и скрыть реализацию всех правил работы с отдельной таблицей, или выборкой на основе SQL запроса, то класс MetaBO призван реализовать самые абстрактные идеи бизнес логики, а точнее правила работы с несколькими таблицами, которые хранят одну бизнес сущность.
Примером может выступать любой, более-менее сложный документ – накладная, карточка и т.д. Наследуясь от класса MetaBO, можно порождать конкретные бизнес сущности и использовать их в самых разных подсистемах БЭСТ5. Так к примеру подсистема Счета Фактуры использует классы подсистем Главная книга (типовые проводки), Общие справочники (классы Партнеры, Подразделения и т.д.). При этом разработчики подсистемы Счета Фактуры не должны знать тонкости реализации классов из других подсистем.
Любая задача программирования может быть решена и с использованием ОПП и структурным методом. Любая! Программирование - было, есть и будет еще очень долго искусством. Если мы сели писать программу – значит у нас есть новая проблема. Новая – не решавшаяся ранее. Способ решения всегда несколько. Единственные наручники, которые можно надеть на разработчика – это единство концепции проекта. Если уж мы используем DbUse ( или x:Use ) то лучше это делать всюду и всеми.
Вот примет: (реализация С++)
EXPORT VMAPI DBUSE()
{
// работа с таблицами DBF
DBFWorkArea *rs = new DBFWorkArea();
…
}
Или
EXPORT VMAPI DBUSE()
{
// работа с базой MSQ SQL Server
MSSQLRecordSet *rs = new MSSQLRecordSet();
Rs->Open(“SEL ECT * FROM MAIN” , “SQLSERVER:MyServer;DataBase=master;”)
…
}