Компонентный подход в программировании


Библиотеки


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

Для Java этот процесс начался значительно раньше и захватил гораздо больше участников в силу более раннего появления платформы и ее большей открытости и стандартизованности. Поэтому далеко не все часто используемые библиотеки классов распространяются в составе платформ J2SE и J2EE. Разработка библиотек .NET ведется, в основном, силами программистов, работающих в Microsoft и некоторых ее партнерах.

В данном разделе дается краткий обзор основных библиотек, подробности см. в [10] и [11].

Основные классы языка Java содержатся в пакете java.lang.

Основные классы C# содержатся в пространстве имен System в сборке mscorlib.

Базовым классом для всех ссылочных типов Java служит класс java.lang.Object.

Этот класс содержит следующие методы.

boolean equals(Object) — предназначен для сравнения объектов с учетом их внутренних данных, перегружается в наследниках. В классе Object сравнивает объекты на совпадение.

int hashCode() — возвращает хэш код данного объекта, используется в хэширующих коллекциях. Должен перегружаться одновременно с методом equals().

String toString() — преобразует данный объект в строку, перегружается в наследниках. В классе Object выдает строку из имени класса и уникального кода объекта в JVM.

Class<? extends Object> getClass() — возвращает объект, представляющий класс данного объекта.

protected void finalize() — вызывается сборщиком мусора на одном из этапов удаления объекта из памяти. Может быть перегружен.

protected Object clone() — предназначен для построения копий данного объекта, перегружается в наследниках. В классе Object копирует поля данного объекта в новый, если класс данного объекта реализует интерфейс java.lang.Cloneable, иначе выбрасывает исключение.

void wait(), void wait(long timeout), void wait(long timeout, int nanos) — методы, приостанавливающие выполнение текущего потока до вызова notify() или notifyAll() другим потоком в данном объекте или до истечения заданного интервала времени.

void notify(), void notifyAll() — методы, оповещающие потоки, которые ждут оповещения по данному объекту. Первый метод "отпускает" только один из ждущих потоков, второй — все.



Базовым типом для всех типов C# служит класс System.Object, который также имеет имя object.

bool Equals(object) — аналог метода equals() в Java.

static bool Equals(object, object) — сравнивает два объекта с помощью Equals() или на равенство обеих ссылок null.

static bool ReferenceEquals(object, object) — сравнивает ссылки на заданные объекты.

int GetHashCode() — аналог метода hashCode() в Java. Должен перегружаться одновременно с методом Equals().

string ToString() — аналог метода toString() в Java. В object выдает только имя типа данного объекта.

System.Type GetType() — возвращает объект, представляющий тип данного объекта.

protected object MemebrwiseClone() — создает копию данного объекта, имеющую те же значения всех полей.

Класс System предоставляет доступ к элементам среды выполнения программы и ряд полезных утилит. Все его элементы — статические.

Поля in, out и err в этом классе представляют собой ссылки на стандартные потоки ввода, вывода и вывода информации об ошибках. Они могут быть изменены при помощи методов setIn(), setOut() и setErr().

Методы long currentTimeMillis() и long nanoTime() служат для получения текущего значения времени.

void exit(int status) — прекращает выполнение Java машины, возвращая указанное число внешней среде в качестве кода выхода.

void gc() — запускает сборку мусора. Время от времени сборка мусора запускается и самостоятельно.

Методы getenv(), getProperties() и getProperty() служат для получения текущих значений переменных окружения и свойств Java машины, задаваемых ей при запуске с опцией –d.

load(), loadLibrary() — служат для загрузки библиотек, например, реализующих native интерфейсы.

void arraycopy() — используется для быстрого копирования массивов.

int identityHashCode(Object) — возвращает уникальный числовой идентификатор данного объекта в Java машине.

Другой класс, содержащий методы работы со средой выполнения, — Runtime.

Данные о среде выполнения можно получить с помощью класса Environment.

В нем имеются методы GetEnvironmentVariables() и GetEnvironmentVariable() для получения значений переменных окружения, методы для получения командной строки, метод Exit(int) для прекращения работы текущего процесса, свойства с данными о машине и текущем пользователе, свойство TickCount, хранящее количество миллисекунд с момента запуска системы, и пр.

Управлять стандартным вводом-выводом можно с помощью класса Console.

Он содержит свойства In, Out, Err, методы для чтения из потока стандартного ввода и для записи в поток стандартного вывода, а также много других свойств консоли.

Для работы со строками используются классы String, StringBuffer и StringBuilder (последний появился в Java 5). Все они реализуют интерфейс последовательностей символов CharSequence.

Класс String представляет неизменяемые строки, два других класса — изменяемые. Отличаются они тем, что все операции StringBuffer синхронизованы, а операции StringBuilder — нет. Соответственно, первый класс нужно использовать для представления строк, с которыми могут работать несколько потоков, а второй — для повышения производительности в рамках одного потока.

Для работы со строками используются классы System.String, представляющий неизменяемые строки, и System.Text.StringBuilder, представляющий изменяемые строки.

В пакете java.lang находятся классы-обертки примитивных типов Boolean, Byte, Character, Short, Integer, Long, Float, Double.

Все числовые классы наследуют классу java.lang.Number.

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

Для форматированного представления чисел используются классы java.text.NumberFormat и java.text.DecimalFormat.

Обертками примитивных типов C# служат следующие структурные типы из пространства имен System.

Boolean, Byte, SByte, Int16, Int32, Int64, UInt16, UInt32, UInt64, Single, Double, Decimal.

Они также содержат аналогичные константы и методы.

Для работы с форматированным строковым представлением чисел используются методы Parse() и ToString() тех же классов с дополнительными параметрами, реализующими интерфейс IFormatProvider. Чаще всего это объекты класса System.Globalization. NumberFormatInfo.

Набор математических функций и констант реализован в виде элементов класса java.lang.Math.

Для генерации псевдослучайных чисел можно использовать как метод Math.random(), так и обладающий большей функциональностью класс java.util.Random.

Для более сложных вычислений можно использовать классы пакета java.math — BigInteger и BigDecimal, представляющие целые числа произвольной величины и десятичные дроби произвольной точности.

Набор математических функций и констант реализован в виде элементов класса System.Math.

Для генерации псевдослучайных чисел используется класс System.Random.

java.lang.Thread — класс, объекты которого представляют потоки в Java машине.

Он содержит методы, позволяющие прервать ожидание данным потоком синхронизационной операции (interrupt()), подождать конца работы данного потока (join()), запустить поток (start()), приостановить выполнение текущего потока на какое-то время (sleep()), получить текущий поток (currentThread()), а также получить различные характеристики данного потока (приоритет, имя, и пр.).

Класс java.lang.ThreadLocal служит для хранения значений, которые должны быть специфичны для потока. Т.е. значение, получаемое методом get() из объекта этого класса, — то самое, которое текущий поток сохранил ранее с помощью метода set().

Классом, представляющим потоки .NET в C#, является System.Threading.Thread.

Текущий поток может быть получен с помощью его свойства CurrentThread.

Этот класс тоже содержит методы Interrupt(), Join(), Start(), Sleep() и др.

В пакете java.lang находится и набор наиболее важных интерфейсов.

CharSequence — интерфейс последовательности символов.

Cloneable — маркирующий интерфейс объектов, для которых можно строить копии. Сам по себе он не требует реализации каких-либо методов, хотя для построения копий нужно перегрузить метод clone(), а лишь позволяет использовать функциональность этого метода в классе Object.

Iterable<T> — интерфейс итерируемых коллекций. Объекты, реализующие этот интерфейс, могут, наравне с массивами, использоваться в инструкции цикла по коллекции.

Comparable<T> — интерфейс, реализуемый классами, объекты которых линейно упорядочены, т.е. любые два объекта этого класса сравнимы по отношению "больше/меньше". Используется, например, для реализации коллекций с быстрым поиском.

Аналогичные интерфейсы в C# следующие.

System.ICloneable — требует реализации метода Clone() для создания копий.

System.Collections.IEnumerable, System.Collections.Generic. IEnumerable<T> — интерфейсы итерируемых коллекций.

System.IComparable, System.IComparable<T> — интерфейсы типов, объекты которых линейно упорядочены.

В C#, в отличии от Java, где шаблонные типы всегда имеют и непривязанный к типам-аргументам интерфейс, шаблоны с типизированным интерфейсом просто добавляются в библиотеки к уже существовавшим там до появления C# 2.0 нетипизированным классам и интерфейсам.

В пакете java.lang также находится ряд классов, объекты которых представляют элементы самого языка — Class<T>, представляющий классы, Enum<T>, представляющий перечислимые типы, и Package, представляющий пакеты.

Все эти классы, а также классы, находящиеся в пакете java.lang.reflect (Field, Method, Constructor) используются в рамках механизма рефлексии (reflection) для доступа к информации об элементах языка во время выполнения программы. На механизме рефлексии построены очень многие среды и технологии, входящие в платформу Java, например JavaBeans.

Для C# аналогичную роль в механизме рефлексии играют классы System.Type, System.ValueType, System.Enum и классы, входящие в пространство имен System.Reflection — MemberInfo, MethodInfo, FieldInfo, и т.д.

Для анализа структуры и элементов массивов во время работы программы можно использовать методы класса java.lang.reflect.Array, позволяющие определить тип элементов массива, получить их значения, создавать новые массивы и пр.

Для манипуляций с массивами — поиска, сортировки, сравнения и пр. — используются методы класса java.util.Arrays.

Аналогом обоих классов Java для работы с массивами служит класс System.Array.

Он содержит как методы анализа структуры массива, так и операции для поиска, упорядочения, копирования и сравнения массивов.

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

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



Пакет java.lang.ref содержит классы для организации сложной работы со ссылками.

Например, класс java.lang.ref.WeakReference представляет слабые ссылки.

Другие классы представляют более хитрые виды ссылок.


В C# слабые ссылки реализуются при помощи класса System.WeakReference.


Пакет java.util содержит классы и интерфейсы, представляющие разнообразные коллекции объектов.

Collection<T> — общий интерфейс коллекций Java.

Collections — предоставляет набор общеупотребительных операций над коллекциями: построение коллекций с различными свойствами, поиск, упорядочение и пр.

Set<T>, HashSet<T>, TreeSet<T> — интерфейс множества объектов и различные его реализации. TreeSet<T> требует, чтобы объекты типа T были линейно упорядоченными, и предоставляет быстро работающие (за логарифмическое время от числа объектов в множестве) функции добавления, удаления и поиска.

Map<K, V>, HashMap<K, V>, TreeMap<K, V> — интерфейс ассоциативных массивов или отображений (maps) и его различные реализации. TreeMap<K, V> требует, чтобы объекты-ключи были линейно упорядоченными, и предоставляет быстрые операции с отображением.

List<T>, ArrayList<T>, LinkedList<T> — интерфейс расширяемого списка и различные его реализации.

BitSet — реализует расширяемый список флагов-битов.

IdentityHashMap<K, V> реализует отображение, сравнивающее свои ключи по их совпадению, а не с помощью метода equals(), как это делают остальные реализации Map<K, V> (и Set<T>).

WeakHashMap<K, V> хранит ключи с помощью слабых ссылок, что позволяет автоматически уничтожать хранящиеся в таком отображении пары ключ-значение, если на объект-ключ других ссылок не осталось.

Много полезных классов-коллекций можно найти вне стандартных библиотек, например, в библиотеке Jakarta Commons [12], части обширного проекта Apache Jakarta Project [13].


Набор интерфейсов и классов коллекций C# находится в пространствах имен System.Collections и System.Collections.Generic. В первом находятся интерфейсы и классы нетипизированных коллекций, во втором — шаблоны. Далее упоминаются только шаблонные типы, если их нетипизированный аналог называется соответствующим образом.

Базовые интерфейсы коллекций — Generic.IEnumerable<T>, Generic.ICollection<T>.

Интерфейс отображений и классы, реализующие отображения — Generic.IDictionary<K, V>, Generic.Dictionary<K, V>, Hashtable (нетипизированный).

Интерфейс и классы списков —Generic.IList<T>, Generic.List<T>, ArrayList (нетипизированный).

BitArray — реализует расширяемый список битов.


Для определения линейного порядка на объектах типа T используется интерфейс java.util.Comparator<T>.

Наиболее часто применяется его реализация для строк — java.text.Collator, абстрактный класс, позволяющий создавать специфические объекты, сравнивающие строки в различных режимах, включая игнорирование регистра символов, использование национально-специфических символов и пр.


Аналогичный интерфейс в C# — System.Collections.Generic. IComparer<T>.

Его реализация для строк — абстрактный класс System.StringComparer.


Классы java.util.Calendar, java.util.GregorianCalendar, java.util.Date и java.text.DateFormat используются для работы с датами.

Первые два класса используются для представления информации о календаре, объекты класса Date представляют даты и моменты времени, а последний класс используется для их конвертации в форматированный текст и обратно.

Класса для представления временных интервалов в стандартной библиотеке нет.

Гораздо более широкий набор средств для работы с датами и временами предоставляет библиотека Joda [14].


Для представления различных календарей используются подклассы System.Globalization.Calendar, тоже находящиеся в пространстве имен System.Globalization.

Для представления моментов времени — System.DateType.

Для интервалов времени — System.TimeSpan.

Для форматированного текстового представления дат и времени — System.Globalization. DateTimeFormatInfo.


Классы java.util.Timer и java.util.TimerTask служат для выполнения определенных действий в заданное время или через определенное время.


Аналоги в C# — System.Threading.Timer и делегатный тип System.Threading.TimerCallback.

Еще одни аналоги находятся в пространстве имен System.Timers сборки System.


Для построения и анализа форматированных строк, содержащих данные различных типов, полезен класс java.util.Formatter.

С помощью реализации интерфейса java.util.Formattable можно определить разные виды форматирования для объектов пользовательских типов.


В C# преобразование в форматированную строку осуществляется методом ToString() с параметром типа System.IFormatProvider. Такой метод есть в типах, реализующих интерфейс System.IFormattable.

Обычно в качестве объектов, задающих форматирование, используются объекты классов System.Globalization. CultureInfo, System.Globalization. NumberFormatInfo и System.Globalization. DateTimeFormatInfo.


В пакете java.util есть несколько классов, представляющих регионально- или национально-специфическую информацию

С помощью объектов класса Currency представляют различные валюты.

Информация о региональных или национально-специфических настройках и параметрах представляется в виде объектов класса Locale.

Набор объектов, имеющих локализованные варианты, например, строки сообщений на разных языках, может храниться с помощью подклассов ResourceBundle — ListResiourceBundle, PropertyResourceBundle.


Аналогичную роль в C# играют классы пространства имен System.Globalization — RegionInfo и CultureInfo.

Для хранения наборов объектов вместе с их аналогами для нескольких культур используются объекты класса System.Resources.ResourceSet.


Работа с различными кодировками текста организуется при помощи классов пакета java.nio.charset.


Работа с различными кодировками текста организуется при помощи классов пространства имен System.Text.


Интерфейс и классы пакета java.util EventListener, EventListenerProxy, EventObject используются для реализации образца "подписчик" в рамках спецификаций JavaBeans (см. предыдущую лекцию).


Класс java.util.Scanner реализует простой лексический анализатор текста.

Более гибкую работу с регулярными выражениями можно реализовать с помощью классов пакета java.util.regex.


В C# работа с регулярными выражениями может быть организована при помощи классов пространства имен System.Text.RegularExpressions в сборке System.


Пакет java.util.concurrent и его подпакет locks содержат набор классов, реализующих коллекции с эффективной синхронизацией работы нескольких потоков (например, разные потоки могут параллельно изменять значения по разным ключам отображения) и примитивы синхронизации потоков — барьеры, семафоры, события, затворы (latches), блокировки типа "много читателей-один писатель" и пр.

Пакет java.util.concurrent.atomic содержит классы, реализующие гарантированно атомарные действия с данными различных типов.


Аналогичные функции выполняют классы пространства имен System.Threading, расположенные как в сборке mscorlib, так и в System.


Пакет java.io содержит класс File, представляющий файлы и операции над ними, а также большое количество подклассов абстрактных классов Reader и InputStream, предназначенных для потокового ввода данных, и Writer и OutputStream, предназначенных для потокового вывода данных.


Аналогичные классы содержатся в пространстве имен System.IO.


Пакет java.nio содержит классы для организации более эффективного асинхронного ввода-вывода.


Аналоги классов из java.nio находятся в пространстве имен System.Runtime.Remoting.Channels в сборках mscorlib и System.Runtime.Remoting.


Классы и интерфейсы, лежащие в основе компонентной модели JavaBeans, находятся в пакете java.beans.

На основе этой модели реализованы библиотеки элементов управления графического пользовательского интерфейса (graphical user interface, GUI) Java.

Одна из этих библиотек (самая старая и не очень эффективная) размещается в пакете java.awt.

Другая, более новая и демонстрирующая большую производительность — в пакете javax.swing.

Одной из наиболее эффективных библиотек графических элементов управления на Java на данный момент считается библиотека SWT (Standard Widget Toolkit [15]), на основе которой разрабатывается расширяемая среда разработки приложений Eclipse [16].


Классы и интерфейсы, лежащие в основе компонентной модели графических элементов управления .NET, находятся в пространстве имен System.ComponentModel.

Эти классы, в основном, расположены в сборке System.

Библиотека элементов GUI находится в пространстве имен System.Windows.Forms в рамках сборки System.Windows.Forms.

Библиотека классов общего назначения для работы с графикой находится в пространстве System.Drawing в сборке System.Drawing.


Интерфейсы и классы для разработки сетевого ПО и организации связи между приложениями, работающими на разных машинах, находятся в пакетах java.net, javax.net, java.rmi, javax.rmi.


Аналогичные классы и интерфейсы находятся в пространствах имен System.Net и System.Runtime.Remoting в рамках сборок mscorlib и System.


Пакеты java.security, javax.crypto и javax.security определяют основные интерфейсы и классы для поддержки обеспечения безопасных соединений, шифрования, использования различных протоколов безопасности и различных моделей управления ключами и сертификатами.


Аналогичные классы и интерфейсы находятся в пространстве имен System.Security в сборках mscorlib, System и System.Security.


Пакеты java.sql и javax.sql содержат основные интерфейсы и классы для организации работы с базами данных, образующие так называемый интерфейс связи с базами данных JDBC (Java DataBase Connectivity).


Аналогичные библиотеки в .NET находятся в пространстве имен System.Data в сборке System.Data.

Определенные там интерфейсы являются основой ADO.NET.


Пакет javax.naming содержит стандартный интерфейс служб директорий, называемый JNDI (Java Naming and Directory Interface) (см. следующие лекции).


Интерфейс и реализация аналогичной службы директорий ActiveDirectory on Microsoft находятся в пространстве имен System.DirectoryServices в сборках System.DirectoryServices и System.DirectoryServices.Protocols.
<


Содержание раздела