Полнота объектно-ориентированных языков

Загрузка хранилищ производится дифференцировано на основе статистики использования информации и параметрами размеров оперативной памяти выделенной для приложения.

Основной массив загружается также дифференцированно по степени важности информации и статистике использования.

Первостепенной информацией с функциональной точки зрения может быть информация БД необходимая для идентификации пользователя в системе. Эта часть информации может пересылаться в первую очередь приложению, или вообще храниться в более доступном месте.

Так же актуально разделить информацию и по статистике использования. Т.е. в файлы первой очереди помещать информацию часто используемую, её передавать сразу за функциональной информацией. Оставшуюся информацию также можно разделить на файлы второй, третьей и т.д. очередей. Часть информации вообще можно оставить как архивную.

На физическом уровне основной массив также делится по частям, где в отдельно хранятся громоздкие элементы массива. Они в свою очередь также разделяются на равные части, что позволяет быстро обращаться к нужному элементу массива и при редактировании работать лишь с малой частью всей громоздкой совокупности.

Главным достоинством такой структуры физического размещения является то, что функции разделения информации можно передать математической модели, учитывающей параметры системы. Таким образом, перераспределение информации происходит динамически, и система сама подбирает наиболее эффективное разделение. Не малую роль имеет и постоянный статистический мониторинг, который позволяет подстраиваться системе к параметрам, которые не учтены моделью.

Литература

1. Конноли Т., Бегг К. Базы данных. Проектирование, реализация и сопровождение. Теория и практика. 3-е издание.:Пер. с англ. / Т. Конноли, К. Бегг. М.: Издательский дом «Вильямс», 2003. С.1440

2. Микляев И.А., Ундозерова А.Н., Кудаева М.В., Универсальная логическая модель базы данных. Вестник Поморского Университета 1/2010. Сер. «Естественные науки» стр. 93-99.

УДК 004.432

ПОЛНОТА ОБЪЕКТНО-ОРИЕНТИРОВАННЫХ ЯЗЫКОВ

Добряк Павел Вадимович, к.т.н., доцент, Уральский государственный технический университет,

Россия, Екатеринбург, goodsoul@mail.ru

В настоящее время объектно-ориентированные языки лидируют по частоте использования в программировании. Большинство создаваемых языков являются объектноориентированными или имеют объектно-ориентированную надстройку. Вместе с тем, возможности языков различны, поэтому возникает вопрос о полноте объектноориентированного языка в смысле реализации в нем объектно-ориентированной парадигмы. Рассмотрим также наиболее популярное семейство языков C++ с точки зрения добавления в них интересных возможностей других объектно-ориентированных языков.

Под объектно-ориентированной парадигмой (ООП) понимается следование принципам абстракции, инкапсуляции, полиморфизма и наследования. Эти принципы формулируются обобщенно, поэтому разработчики объектно-ориентированных языков имеют достаточную свободу в выборе конструкций языка и полноты реализации этих принципов. Вместе с тем, с течением времени ООП в рамках этих принципов эволюционировала, и сменилось понимание, что должен представлять собой код программы:

39

1. В момент возникновения ООП код программы представляет собой множество объектов, обменивающихся сообщениями (классы, вообще говоря, необязательны).

2. Большая часть программного кода на сегодня представляет собой иерархию классов, экземпляры которых вызывают друг у друга методы (сообщения предыдущего этапа «маскируются» под вызов методов).

3. При разработке распределенных систем и повторно-используемом коде акцент смещается на сервисы, предоставляемые другим информационным системам. Код программы начинает представлять собой классы, реализующие интерфейсы.

«Чистые» языки, реализующие одну парадигму, - большое исключение, большинство языков поддерживают несколько парадигм. Рассмотрим две парадигмы, которые практически полностью «растворились» в ООП в языках общего назначения.

Модель фрейм-слот появилась в системах искусственного интеллекта. Если мы сравним её с ООП, то увидим, что у двух парадигм больше сходства, чем отличий. Фреймы являются аналогами классов, слоты - свойств и методов. Фацеты также можно увидеть в ООП - это значения свойств по умолчанию и конструкторы и деструкторы (разновидности демонов). В свою очередь, демоны - аналоги триггеров в мире баз данных. Если триггеры перенести в ООП, то появится возможность помимо конструкторов и деструкторов писать модификаторы - действия при изменении объекта. Поскольку сейчас развиваются гибридные технологии из языков программирования, баз данных и искусственного интеллекта (объектно-ориентированные, дедуктивные и интеллектуальные базы данных), то уместно предлагать выработать общую терминологию в этих сферах.

Событийное программирование родственно многопоточному программированию и появилось в программах, которые должны реагировать и, возможно, обрабатывать одновременно несколько действий внешней среды. Однако, при появлении графических пользовательских интерфейсов, за основу языков взяли ООП, так как оказалось, что совместное определение данных и кода (принцип инкапсуляции) удобно для программирования всевозможных кнопок и движков интерфейса программы. Возник вопрос, как в программе представлять события. Логически верно было реализовать события в виде виртуальных функций, но это оказалось неудобно, так как потребовались большие таблицы вызовов виртуальных функций. Пришлось выйти за пределы стандартов языков и создать таблицы соответствий событий и методов, их обрабатывающих, которые могут быть как спрятанными от программиста (как, например, в C++ Builder), так и открытыми (в Visual C++). Вместе с тем, несовместимости между ООП и событийной парадигмой нет, если рассматривать сообщения как события, у которых только один обработчик. Событийная парадигма изящно реализуются в С#, где у классов помимо свойств и методов появляются события.

Лидирующее положение в программировании занимают языки семейства С++ (к которым отнесем Object Pascal, C++, Java и С#). Они являются мультипарадигменными и дают возможность писать программы разными стилями. Код программы представляет собой «матрёшку» вложенных парадигм, как показано на рис. 1. Возможно, благодаря такой структуре эти языки и стали популярными, так как наиболее естественно писать математические формулы приближенно к записям в математике (в отличие от Lisp). Принцип мультипарадигменного программирования - писать отдельные части программы приближенно к наиболее удобной и общепринятой форме вне программирования [1].

Объектная надстройка Процедуры и функции Структурные операторы

Математические и логические операторы

Рис. 1. Вложенность парадигм в языках семейства C++

40

Язык С# имеет более сложную структуру, чем показано на рис. 1, так как поддерживает функциональное программирование (лямбда-нотация), декларативное программирование (Linq) и теги.

Естественно ли жесткое разделение на уровни парадигм, как тому привыкли программисты на C++, или возможно более сложное взаимодействие -взаимопроникновение, надстройка или даже слияние слоев? В Smalltalk структурные операторы - это вызов методов у служебных классов, например, условный оператор - метод у объекта истина. Можно сформулировать следующее требование полноты ООП - структуры языка, выходящие за пределы ООП, должны иметь возможность быть представленными как объекты.

Интересный пример слияния слоев дает язык BETA. Рассмотрим, что есть общего у класса и функций. Статические переменные функции похожи на свойства объектов. При создании экземпляра класса мы используем имя класса как функцию, передавая аргументы конструктору, - разновидность полиморфизма (языки семейства C++ кроме Object Pascal). В языке BETA есть единая конструкция языка - паттерн (не путать с термином паттерн из объектно-ориентированного проектирования), которая обобщает классы и функции, то есть фактически два верхних слоя «матрешки» парадигм слиты в один слой. Интересно, что при вводе паттернов, исчезает необходимость в шаблонах - мы можем передавать классы как аргументы в паттерн. При этом код на C++ подобном языке может выглядеть так: class A (class B) {public: B b[10];};

A(int) a; a.b[1] = 1;

Возможна и многослойная структура. При программировании на языках семейства C++ мы можем вкладывать классы внутрь других классов. Нет теоретических препятствий размещать классы внутри функций и структурных операторов. В этом случае можно сформулировать второе требование - возможность определения классов в любом месте программы. Пример: class A { class B {...}; void method

{

class C {...}; if

{ class D{...}...;}...

} ...

};

Если предположить возможность математических операций над классами, например, сложение классов как объединение свойств и методов (в языке C++ это реализовано как множественное наследование), то «матрешка» парадигм становится бесконечной, потому что появляется новый слой формул уже над классами. Например:

class A {public: int i;}; class B {public: int j;};

(A + B) object; cin >> object.i; cin >> object.j;

Видами взаимоотношений между классами (объектами) в языках семейства C++ являются агрегация, наследование и вызов методов. Эти взаимоотношения являются ортогональными. Если обратить внимание на другие языки ООП, то в них могут быть метаклассы (классы, принадлежащие классам). К пониманию метаклассов легко перейти, проанализировав следующий код C++: class A {...};

A a;

41

Первая строка подобна второй. Если «а» - экземпляр класса «А», то «А» мы можем рассматривать как экземпляр служебного класса «class». В Smalltalk есть служебные метаклассы - класс, к которому принадлежат созданные в программе классы, и класс функций. В Smalltalk три уровня в измерении метаклассов: метакласс - класс - экземпляр класса. В языке CLOS может быть много уровней за счет создаваемых программистом метаклассов. Таким образом, третье требование полноты парадигмы - возможность многоуровневых пользовательских метаклассов. В этом случае статические свойства в классе можно рассматривать как свойства самого класса или экземпляризируемые свойства метакласса (то есть модификатор static у свойства становится не нужным). Пример реализации счетчика числа экземпляров:

class A {public: int count;};

A B {

B

{count ++;}

};

B b;

cout << B.count // 1;

Таким образом, у нас существует четыре ортогональных направления взаимоотношений классов

Рис. 2. Взаимоотношения классов

Настолько ли эти направления независимы друг от друга, что нет гибридных вариантов взаимодействий? На практике часто возникают ситуации, когда отношения между классами похожи на агрегацию и на наследование. Так, например, вектор - частный случай матриц, но матрицу можно представить как вектор векторов. Область - часть государства, но при этом её структура подобна государству. Разница в языковых структурах наследования и агрегации в том, что классы-предки пишутся перед телом класса и не имеют названия экземпляра. Гибрид станет возможным, если мы перенесем классы-предки с ключевым словом inherit внутрь тела класса:

class A {public: int i;};

class B {public: inherit A a;};

B b;

b.a.i = 1;

cout << b.i ; // 1

Под наследованием понимают три разновидности:

1. Возможность использовать атрибуты класса-предка как свои собственные в классе-потомке.

2. Возможность добавления новых свойств и методов к классу-предку.

3. Возможность перегрузки свойств и методов класса-предка.

Когда речь идет об определении метода с тем же именем, что и в классе-предке, обычно имеется в виду, что у класса-потомка будет своя реализация метода. В конструкторе класса-потомка мы можем вызывать конструктор класса-предка. В языке CLOS программист сам определяет последовательность компоновки метода из методов-предков с помощью

42

ключевых слов before, after и даже around - в начале, конце или и в начале и в конце будет вызываться метод предка с тем же названием, что и в потомке. Требование полноты ООП: возможность программиста управлять компоновкой методов при наследовании.

Дискуссия о том, нужно ли множественное наследование, повторяется при появлении каждого нового языка. На этот счет есть разные мнения [2]. Несомненно, что множественное наследование порождает массу проблем, когда элементы классов-предков имеют одинаковые имена [3]. В то же время, в некоторых предметных областях множественное наследование -естественное представление взаимосвязи классов. Стоит ли лишать программистов такой возможности? На взгляд автора статьи, если можно обойтись без множественного наследования, нужно это сделать, но если оно - простое решение, не стоит от него отказываться. Разработчик компилятора должен его реализовать, а дело программиста -использовать его или нет.

Обязательно ли иерархическое наследование? [4] Иногда говорят о гетерархиях (решетках наследования). Если речь идет о наследовании как возможности использовать свойства класса-предка как свойства класса-потомка, то наследование может быть полным или частичным. В последнем случае оно может быть циклическим. Нет принципиальных трудностей реализовать цикл наследования: class A, B; class A : public B { private: int a1; public: int a2;

}

class B : public A { private: int b1; public: int b2;

}

A a;

B b;

cin >> a.a2; cin >> a.b2; cin >> b.b2; cin >> b.a2;

Подобное наследование приближает систему классов к семантическим сетям, в которых понятия соединены между собой сетью, и проблематично выделить иерархии.

Таким образом, на рис. 2 измерения наследования и агрегации объединяются в одну линию, которая может превращаться в петлю.

В языках семейства C++ под объектами понимаются классы и экземпляры классов. Однако классы имеют явно урезанные возможности по сравнению с экземплярами. Многоуровневое метаклассирование, возможность объявлять классы в любом месте программы, операции над классами, передача классов в качестве аргументов дополняют возможности классов. Для полной реализации требования класс - тоже объект не хватает ссылок (или указателей) на класс. Они могут использоваться для динамического объявления экземпляра, когда класс объекта заранее неизвестен: class& A;

class B {...};

A = &B;

A a;

Мы рассмотрели полноту реализации принципов ООП в языках семейства С++ и показали, что расширение возможностей языков в большинстве случаев не требует введения дополнительных языковых конструкций, а в некоторых случаях конструкции языка даже

43

становятся лишними (статические свойства, шаблоны). Такое расширение заменяет иерархическую структуру программы на вложенные сети внутри сетей [5].

Литература

1. Прохоров В.В. О мультиметафорном подходе к построению языков и программных средств. // Труды международного семинара «Искусственный интеллект в образовании», часть II. -Казань: КГТУ, 1996. с. 49-54.

2. Легалов А. О стрельбе по множественному наследованию. // Открытые системы №5-6, 2001 г.

3. Труб И. О проблемах множественного наследования. // Открытые системы №2, 2001 г.

4. Люри Дж., Мансур Ш. Преодоление иерархий. //Открытые системы, 24.10.2001.

5. Добряк П.В., Калмыков А.А. Альтернативный подход по организации структур данных в объектно-ориентированных языках. Практика приборостроения №4[9], 2004. - с. 76 - 79.

УДК 330.45

АДАПТИВНЫЙ МЕХАНИЗМ УПРАВЛЕНИЯ ПРЕДПРИЯТИЕМ И ИМИТАЦИОННОЕ МОДЕЛИРОВАНИЕ

Куимова Галина Михайловна, доцент кафедры экономики и управления ДВГТУ (филиал), Россия,

Находка, kuimovag@mail.ru

В современном мире экономическая наука является своеобразным “китом”, позволяя обществу понимать и реализовывать закономерности его материального существования. Экономическая наука в настоящее время стала делиться на теоретическую науку, которая как бы сохранила в своем составе традиционные методы и подходы, и экспериментальную науку, в которой новые знания о субъекте и предмете знания могли быть достигнуты лишь с применением специальной методологии и специальных опытных приемов.

Каждый отдельный предприниматель или руководитель предприятия, подразделения может быть сегодня рассмотрен как ученый, исследователь в отслеживании конкретного экономического действия, а следовательно может быть приравнен к специалисту в другой науке - науке управления. Напомню, что любой научный труд уникален и осуществляется весьма индивидуально. Причем эта уникальность выражается не только в новизне полученных результатов, но и выборе и оригинальности путей, способов и средств их получения.

Экономическая наука, таким образом, оказалась разделенной на две самостоятельно существующие ветви: экономическую практику (конкретную экономику) и экономическую теорию (научная экономика). Каждая из этих двух ветвей развивается в своем направлении, иногда пересекаясь. Практическое действие становится все более зависимым от отслеживания совокупности внешних условий, оказывающих очень важное влияние на результат, а теоретическая наука абстрагируется от них.

В управлении предприятием классические модели принятия решений всегда являются оптимизационными с целью получения оптимальной практической рекомендации, и они вынуждены использовать упрощенное представление действительности, что часто приводит к тому, что эти рекомендации теряют практическую ценность. Модели принятия решений могут ограниченно отразить действительность не только из-за дефицита данных и несовершенства теорий управления и моделей, но прежде всего ввиду огромного разнообразия явлений и связей в реальной хозяйственной жизни.

Большинство этих параметров носит вероятностный характер и, что самое главное, являются нестационарными. Планирование и управление по усредненным характеристикам не дает должного эффекта, так как пока оно ведется, изменяются и сама система, и ее окружающая среда, внешние условия. Все это усугубляется нестационарным характером вероятностных процессов. В результате применение формальных математических моделей затруднено из-за большой размерности экономической системы, недостаточной априорной

44