IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  Lotus  >

Проектирование составных приложений: Проектирование компонентов

developerWorks
Опции документа

Опции документа, требующие включения JavaScript, не отображаются

Обсудить


Выскажите мнение об этой странице

Помогите нам улучшить содержание


Уровень сложности: средний

Крейг Волперт, старший инженер-программист, IBM
Джо Грант, старший инженер-программист, IBM

25.11.2008

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

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

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

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

Поделиться...

digg Разместить на Digg
del.icio.us Разместить на del.icio.us
Slashdot Разместить на Slashdot!

Модель составных приложений уже известна разработчикам WebSphere Portal. Этот подход был распространён и на IBM Lotus Notes V8, что позволило разработчикам Lotus Notes оформлять приложения Lotus Notes в виде одного или нескольких компонентов составного приложения. IBM Lotus Domino Designer V8 теперь поддерживает возможность использования брокера свойств, а также предоставляет пользователю более интуитивный интерфейс. Lotus Notes V8 также поддерживает вставку компонентов Eclipse, так что в составном приложении может использоваться любое сочетание компонентов Lotus Notes и Eclipse. Это можно реализовать при помощи прозрачной интеграции (совместное представление компонентов в одном пользовательском интерфейсе) или, при расширении, с помощью брокера свойств, обеспечивающего взаимодействие компонентов друг с другом. Определять составные приложения можно при помощи редакторов Composite Application Editor или WebSphere Portal Application Template Editor.

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

Предварительные требования

Предполагается, что читатель знаком с составными приложениями Lotus Notes. Ознакомьтесь с введением в составные приложения в соответствующем разделе справки по IBM Lotus Domino Designer.

Руководство "Пример составного приложения для IBM Lotus Notes V8 по отслеживанию интересов покупателей" можно использовать для приобретения практических навыков сборки основанных на NFS составных приложений, включающих в себя компоненты NFS и компоненты Eclipse, взаимодействующие друг с другом на межкомпонентном уровне.



В начало


Работаем совместно

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

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

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



В начало


Типы компонентов

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

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

Пример приложения управления продажами состоит из трех основных доменов приложения:

  • Ядро приложения управления продажами, которое отслеживает компании и продажи
  • Приложение для обсуждения, которое позволяет обсуждать проведение продаж
  • Юридическое приложение, которое отслеживает контракты, заключенные с клиентами и версии контрактов

Компоненты, ориентированные на домен

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

В примере приложения такие компоненты как CompanyList, SalesLeadList, SalesLeadDetail и SalesLeadEdit являются ориентированными на домен компонентами. См. рисунок 1.


Рисунок 1. Примеры ориентированных на домен компонентов
Примеры ориентированных на домен компонентов

Примеры ориентированных на домен компонентов

Примеры ориентированных на домен компонентов

Примеры ориентированных на домен компонентов

Примеры ориентированных на домен компонентов

Компоненты контекста домена

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

Альтернативный подход к преобразованию приложения в составное заключается в том, чтобы сначала создать компоненты контекста в виде, подходящем для вставки в другие составные приложения. Этот подход демонстрирует ценность повторного использования компонентов на ранней стадии перехода на архитектуру составных приложений. Если приложение большое и сложное, для его полной конвертации могут потребоваться длительные сроки. Если приложение разрабатывалось под другую архитектуру (например, приложение для текстовых терминалов, обслуживаемое сервером), то полная конвертация не имеет смысла. Но так же как Web-сервисы предоставляют доступ к серверным системам, компоненты контекста домена могут извлекать данные, содержащиеся в этих системах (возможно, с помощью тех же Web-сервисов) для повторного использования в новых проектах составных приложений.

В примере приложения компоненты CompanySummary, LeadSummary и LeadList ConstrainedByCompany являются компонентами контекста домена. На рисунке 2 можно увидеть, как они используются в домене приложения обсуждения и юридического приложения для отображения базовой информации в контекстах этих приложений.


Рисунок 2. Примеры компонентов контекста домена
Примеры компонентов контекста домена

Примеры компонентов контекста домена

Общие и вспомогательные компоненты

В ходе разработки составного приложения мы имеем дело с элементами, не привязанными жестко к домену приложения. Это полезные компоненты, которые могут пригодиться каждому, кто разрабатывает составные приложения.

В нашем примере приложения компоненты Pager, Browser, RSSReader и MailSearch являются вспомогательными. В Lotus Notes содержится несколько компонентов общего использования. В качестве примера можно привести входящий в поставку продукта пример приложения Lead Manager, в котором используются компоненты для имен и адресных книг, а также приложение Managed Browser.



В начало


Деятельность центра разработки

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

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

Другая причина для организации доступного всем представления - выработка языка для разработки составных приложений. Процесс проектирования и разработки составных приложений такой же, как и для любых других приложений. Он предполагает установку требований, спецификаций, планирование тестирования и развёртывания приложения. Составные приложения немного отличаются тем, что при разработке компонентов не всегда имеется чётко определённое целевое приложение, и сборка приложения может производиться особым образом. Осуществляя взаимодействие по процессам написания документации, разработке планов тестирования и организации развёртывания приложения, можно повысить эффективность и минимизировать затраты. Более подробно это будет раскрыто в статье этой серии "Разработка составных приложений: управление процессом".

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

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

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

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

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

Самый важный технический аспект для рабочей группы состоит в поддержании единого набора типов данных. Компоненты взаимодействуют друг с другом посредством передачи данных от свойств к действиям по связям. Эти связи нельзя создать, если в обеих конечных точках не будут использоваться одни и те же типы данных. В обоих компонентах может применяться понятие даты. Но пока даты не будут одинаково определены (пространство имен, имя, тип), компоненты не смогут установить соединение. Рабочая группа (или даже один человек в качестве владельца типа данных) может поддерживать список общих типов данных для всей компании. По мере того, как каждая группа представляет ожидаемую функциональность, она должна также определять различные типы данных для свойств и действий. Можно определить типы данных, соответствующие существующим в компании определениям, и для них можно использовать соответствующие общие определения. Новые и уникальные типы могут быть добавлены в список определений типов компании.

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

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



В начало


Шаблон компонентов

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

Этот вопрос будет подробно рассмотрен в одной из следующих статей настоящей серии: "Проектирование составных приложений: конструктивные шаблоны".



В начало


Разбиение на компоненты

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

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

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

Разрабатывать компоненты при преобразовании существующего приложения и проще, и сложней. Проще, потому что у вас уже имеется проект приложения. Сложнее, так как нужно искать компромисс между использованием того, что уже есть, и проектированием с учётом многократного использования.

В случае приложения Lotus Notes можно работать с некоторыми фундаментальными типами пользовательского интерфейса. В будущей статье "Разработка компонентных приложений: компоненты Lotus Notes" будет подробно рассмотрен пример конвертирования базы данных дискуссий в составное приложение. Принципы, очерченные в этой статье, в общем, применимы ко многим типам приложений Lotus Notes.

Приложения, основанные на Eclipse, предоставляют вам то преимущество, что они уже основаны на представлениях, которые легко перевести непосредственно в компоненты. В Lotus Notes V8 возможности взаимодействия и повторного использования ещё шире. Уровень разбиения, выбранный для перевода вашего приложения на Eclipse, может быть неоптимальным для оформления вашего приложения в виде составного. С помощью представлений Eclipse (или перспектив) можно применить метод последовательного разбиения для порождения компонентов.



В начало


Межкомпонентное взаимодействие

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

Свойства

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

Один из подходов, позволяющих обойти это ограничение, заключается в определении метода для сериализации. Детали сложного элемента могут, например, быть представлены структурой данных XML и, соответственно, сериализованы в строку. Эта методика часто используется в Web-сервисах. Но этот подход имеет некоторые недостатки. Прежде всего, каждый раз, когда изменяется элемент, нужно передавать заново всю структуру. Этот подход применим только для групп настроек, которые имеют связь на сервере. Кроме того, уменьшаются шансы на то, что компонент сможет взаимодействовать с компонентами других доменов. Хотя отдельные элементы могут иметь общие типы, если вся структура данных специфична для домена приложения, для того, чтобы другой компонент мог воспользоваться ей, он должен знать эту структуру. Такие ограничения удаляют архитектуру от идеи слабой связи.

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

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

Например, во включенном в статью приложении по проведению продаж, многие компоненты передают свойство ViewState. Это свойство содержит заранее заданное значение вида операции или перехода состояния, которые компонент желает передать на уровень приложения. Например, компонент Company Edit устанавливает для свойства значение #company.save после сохранения данных или #company.close после нажатия на кнопку "Закрыть". Во время сборки эти компоненты связаны с компонентом, переключающим страницы, который ставит в соответствие уведомлениям об этих событиях определенные переходы между страницами.

Действия

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

Как и в случае со свойствами, простейший способ их использования заключается просто в получении данных. Компонент может получить свойство и просто хранить его, отложив дальнейшие действия. Или он может произвести отдельную операцию с данными, например обновление значения поля ввода. Для таких действий типы данных непосредственно соответствуют полю, которое они представляют.

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

В этой статье рассматриваются операции в виде сервисов для действий, но только в том случае, когда они принимают один аргумент. Что, если у вас есть сервис, который вы хотите оформить в виде компонента, но он принимает на вход несколько значений? Сейчас вы можете передавать действию только один аргумент. Есть два варианта поддержки более сложных сервисов. Во-первых, можно использовать тот же подход, что и для свойств - сериализовать необходимые аргументы в простой строковый тип. Например, почтовый компонент использует действие с типом данных, содержащим строку "mailto:". Строка эффективно сериализует список адресатов, копий, скрытых копий, а также тему и текст сообщения. Как и в случае с сериализованными значениями свойств, недостаток заключается в ограничении области использования типа, вероятно, уникального для этого действия, что ограничивает универсальность при взаимодействии. Вдобавок, если входные значения берутся из различных свойств, объединение их в единую сериализованную строку является затруднительным.

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



В начало


Заключение

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



Ресурсы

Научиться

Получить продукты и технологии

Обсудить


Об авторах

Крейг Волперт (Craig Wolpert) - старший инженер-программист, работающий в программе внедрения IBM Lotus Software ISV.


Джо Грант (Jo Grant) - старший инженер-программист IBM Lotus, специализирующийся на технологиях на основе Eclipse.




Выскажите мнение об этой странице


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



 


 


 


Поделиться этой статьей:

забобрить забобрить memori сохранить в memori




В начало


IBM обладает всеми авторскими правами касательно информации, расположенной на developerWorks. Использование информации приведенной на этом ресурсе без явного письменного разрешения от IBM или первоначального автора запрещены. Если Вы желаете использовать информацию с developerWorks, пожалуйста воспользуйтесь регистрационной формой для того, чтобы связаться с нами запрос на использование материалов developerWorks Россия.
    IBM в России Конфиденциальность Контакты