что такое пакет в программировании

Пакеты, системы, модули, библиотеки — КАКОГО?

По моим наблюдениям, минимум раз в неделю в списке c.l.l или другом Lisp-списке «новички» путаются в том, что связано с пакетами. Говорят о «загрузке» пакета, «требовании» (requiring) пакета, удивляются тому, что после загрузки системы нужно пользоваться маркерами пакетов и т.д. Меня это раздражает, думаю также, что это может быть одной из причин, почему начинающие считают, что использование библиотек в Lisp сложнее, чем есть на самом деле.

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

Прежде всего следует иметь ясную голову. Термин «пакет» сильно перегружен. В дистрибутивах Linux вроде Debian или Gentoo есть «пакеты», «пакеты» есть в языках программирования Java, Perl или Python. Вполне вероятно, что вы пришли в Lisp с предвзятым мнением относительно того, что такое «пакет» или чем он должен быть.

Пакеты

Пакетом в Common Lisp называется полноправный элемент языка, семантика которого четко определена стандартом. Более того, из всех обсуждаемых на этой странице терминов, этот — единственный, имеющий (в контексте Common Lisp) однозначное определение. Пакеты — это, строго говоря, контейнеры для символов. Можно сказать, что они нужны для помощи в организации отдельных пространств имен в ваших программах.

В Common Lisp есть функции и макросы для создания, изменения, исследования и удаления пакетов. Очень хорошее введение в пакеты (и символы) можно найти в главе 21 великолепной книги Practical Common Lisp Питера Сайбела. Определение термина находится в главе 11 (онлайн-версии) стандарта ANSI Common Lisp specification.

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

Кроме того, если ваш Lisp жалуется, что не может найти какой-то пакет, это означает, что пакета как Lisp-объекта нет в образе (т.е. FIND-PACKAGE возвращает NIL ), потому что его еще никто не создал. Это не означает, что Lisp-машина поискала в файловой системе и ничего не нашла. (Частая причина такой неудачи состоит в том, что события происходят в неправильном порядке. Об этом ниже.)

Системы

Системы, в отличие от пакетов, даже не упоминаются в стандарте. Тем не менее, опытные Lisp-программисты знают этот термин, поскольку им потребуютется знать и применять какой-то инструмент определения систем. Наиболее заметный сегодня — ASDF (используется большинством Lisp-библиотек с открытым исходным кодом); другой известный инструмент определения систем, гораздо старше ASDF — MK:DEFSYSTEM. Некоторые разработчики также поставляют свои инструменты определения систем вместе с дистрибутивами, см. например, Common Defsystem для LispWorks.

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

Кроме того, инструмент определения систем обычно может намного больше — Common Defsystem может, например, интегрировать файлы библиотек типов COM, ASDF полностью расширяем и использовался, среди прочего, для компиляции файлов на C. Он также часто используется для определения тестовых наборов описываемой системы.

Хотя ASDF и весьма популярен, он не вездесущ. Он идет предустановленным со многими Lisp-системами вроде SBCL, OpenMCL или AllegroCL, вероятнее всего, что он загрузится и в других Lisp-системах, но этот факт не делает его частью Common Lisp. Это набор кода без явной спецификации и с разными версиями, которые бывают несовместимы между собой.
Поди пойми…

Модули

Например, в LispWorks можно использовать

для загрузки парсера, способного читать определения на C, но это не сработает на OpenMCL. Также можно вызвать

для загрузки ASDF на OpenMCL, но не в LispWorks.

Библиотеки

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

И, по соглашению, а может из-за недостатка фантазии, может сложится и часто складывается ситуация, когда библиотека «Ку» идет с определением системы «Ку», которую можно загрузить как модуль «Ку». После загрузки кода получите новый пакет, называемый «Ку». Четыре разных сущности с одинаковым именем! Я допускаю, что это сбивает с толку, но надеюсь, что несколько предыдущих абзацев помогли слегка прояснить ситуацию.

Но у меня все еще ничего не работает!

Часто люди жалуются, что они не могут скомпилировать файл, содержащий код вроде этого:

Почему так? Почему я могу загрузить этот файл, но не могу скомпилировать его? И почему я могу скомпилировать его после загрузки? Не странно ли?

Нет, не странно. Компилятор читает первую форму (которая является инструкцией скомпилировать — если необходимо — и загрузить систему CL-PPCRE, но не выполнить ее. В конце концов, компилятор заинтересован лишь в компиляции кода. После выполнения первой формы он переходит ко второй форме, к определению функции. Здесь возможно сообщение об ошибке, так как Lisp-сканер, пытающийся читать эту форму, обнаружит последовательность символов «cl-ppcre:scan», которая должна обозначать внешний символ из пакета CL-PPCRE, но самого пакета CL-PPCRE еще нет. В процессе загрузки системы CL-PPCRE, кроме всего прочего, создается пакет CL-PPCRE, но этого еще не произошло. Читайте главу 3 CLHS.

Можно воспользоваться EVAL-WHEN для указания компилятору загрузить CL-PPCRE перед чтением второй формы. Следует, однако, найти другой способ организации своего кода. Первая форма — это просто обявление того, что ваш код зависит от системы CL-PPCRE. Такое не должно находиться в том же файле, что и Lisp-код. Напишите определение системы для вашей программы и поместите зависимости туда.

Источник

Что такое пакет в программировании

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

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

Пакет прикладных программ (application program package) – комплекс взаимосвязанных программ для решения задач определенного класса конкретной предметной области.

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

Характеристика пакетов прикладных программ. Классифицируются:

Основные тенденции в области развития ПОС:

Особенности: высокие требования к технической части обработки систем, наличие библиотеки встроенных функций и объектов, интерфейсов и баз данных.

Пакеты общего назначения

Элементы CASE-технологии в процессе корректировки содержат:

Серверы БД – успешно развивающийся вид программного обеспечения:

DAL – Data Access Language для создания запросов на выборку данными из сети;

SQL – для распределения запросов.

Самая большая проблема серверов баз данных – обеспечение целостности базы данных.

Генераторы отчетов (серверы отчетов):

Сервер отчетов включает:

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

При описании текстовых процессоров следует выделить две группы программных продуктов этого типа. Первая группа ориентирована на создание документов разной степени сложности с мощными средствами форматирования и включения графики. Типичным представителем этой группы является WinWord. Вторая группа текстовых процессоров (их часто называют текстовыми редакторами) ориентирована для работы с чисто текстовыми файлами, среди которых могут быть тексты программ, написанные на различных языках, конфигурационные файлы, файлы настройки и др. Ярким представителем таких программных продуктов является MultiEdit версий, начиная с 5.0. Этот текстовый процессор имеет мощную систему контекстной замены, встроенный язык макрокоманд на уровне Visual Basic, средства поддержки внутренней среды, средства помощи при наборе ключевых слов.

Возможности: автоматическое форматирование документов, вставка рисунков объектов и графики, составление оглавления и указателей, проверка орфографии, шрифтовое оформление, подготовка шаблонов документов.

Развитие данного направления программных продуктов является издательские системы.

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

Средства презентационной графики

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

Яркий представитель – Microsoft Office. Компоненты пакета могут работать изолированно друг от друга. Основное достоинство – их разумное сочетание друг с другом.

Характеристика интегрированного пакета:

— DDE и OLE (динамическая компоновка объектами);

Методоориентированные пакеты прикладных программ

Современный табличный процессор Excell:

Офисные пакеты прикладных программ (ППП):

Браузеры, средства создания интернет-страниц и прочего;

Электронная почта – важный компонент;

— Различаются платформами на которых работают, ценой, условиями распространения, поддерживаемыми транспортными протоколами, интерфейсами и сетями;

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

Настольные издательские системы

Программные средства мультимедиа

Основное назначение этого класса программных продуктов:

Создание и использование аудио- и видео информации для расширения информационного пространства пользователя.

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

Системы Искусственно Интеллекта (ИИ)

Данный класс ПП реализует отдельные функции интеллекта человека.

Основными компонентами системы ИИ являются:

Разработка интеллектуальных систем ведется по следующим направлениям:

Интеллектуальный интерфейс включает:

Модуляция/демодуляция голоса – главный фактор в отставании проектирования интеллектуального интерфейса.

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

Классификация семантических сетей:

1. Однородные (с единым типом взаимодействий);
2. Неоднородные (с различными типами взаимодействий).

По типам отношений делятся:

Источник

Теория программирования: пакетные принципы и метрики

Чтобы применять любые принципы правильно, сначала нужно их понять — то есть осознать, откуда они взялись и для чего нужны. Если применять вслепую всё, что угодно — результат будет хуже, чем если бы мы вообще не использовали эти принципы. Я начну издалека и сначала расскажу про абстракцию.

Что есть абстракция?

Это обобщение существенного и удаление несущественного, так как мир настолько сложен, что запрограммировать удаётся только его существенные части. Если попытаемся запрограммировать всё — мы потонем, поэтому абстракция помогает нашему мозгу «впихнуть невпихуемое», как это умеют делают военные (а программисты — пока нет):

Наши проблемы идут от мозга и от того, как устроена наша память. В отличие от хорошего хранилища долговременной памяти, кратковременная устроена по типу stack:

Еще мы используем Chunking (группировку) всякий раз, когда важно запомнить что-то большое. Например, чтобы запомнить число 88003334434, мы разделим его на группы по типу телефонного номера: 8-800-333-44-34. Для нашего мозга получится 5 объектов, которые запомнить легче, чем пытаться удержать число целиком или отдельно каждую его часть.

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

Поэтому, чтобы совладать с неподъёмно сложными системами, изобретают архитектуру, используя абстракцию. Это не цель, а инструмент, и одновременно — необходимое зло, так как все эти классы, супер-паттерны и прочие шутки не от нашей хорошей жизни.

Но как построить абстракцию, не сделав хуже?

Существует два понятия: cohesion (связность) и coupling (связанность). Они относятся в первую очередь к классам, но в целом и ко всем остальным сущностям. Разницу мало кто видит, так как звучат они почти одинаково.

И, хотя оба означают связь, coupling понимают в негативном ключе. Один объект завязан на другой в плохом смысле, если, ломая один из объектов, ломается всё остальное по цепочке. Cohesion несёт в себе позитивную ноту. Это группировка, в которой то, что близко по смыслу — лежит в одном месте и взаимодействует примерно с теми же местами, опять же близкими по смыслу.

Для того, чтобы понять, coupling у вас или cohesion, существуют проверочные правила. Их сформулировал инженер и специалист в области информатики Роберт Мартин еще в 2000 году, и это — принципы SOLID:

Что есть пакет?

Пакет — это группа единиц кода. Причем, пакеты – это не обязательно пакеты Maven или Composer, или npm. Это программные модули, — то, что вы выделяете в namespaces или иным способом группируете.

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

И того, кто эти пакеты пилит, обычно волнуют два вопроса: Как правильно формировать пакеты и как работать с зависимостями пакетов?

Как их правильно формировать?

Собственно, cohesion и coupling, как основополагающие принципы, отлично работают и для пакетов. Но сработает ли SOLID для пакетов?

Да, но не совсем. Оказалось, что существуют ещё 6 принципов от того же Роберта Мартина, сформулированные в том же году. Часть из них относится к cohesion, и это о том, как дизайнить код: REP, CCP, CRP. Другая часть — это coupling (то есть использование пакетов): ADP, SDP, SAP — и это о том, как сделать так, чтобы один пакет не завязался на другой и чтобы всё нормально работало:

1 принцип – REP (Reuse-Release Equivalency Principle)

На сегодняшний день этот принцип выглядит до смешного очевидным, но не забываем, что сформулирован он в 2000 году, когда не было таких замечательных штук, как Maven, Composer и прочих, а пакетные релизы были не частыми.

Принцип гласит: «The granule of reuse is the granule of release. Only components that are released through a tracking system can effectively be reused. This granule is the package. — что переиспользуем, то и релизим. Эффективно переиспользовать можно только компоненты, релизнутые через системы версионирования. Такие компоненты называются пакетами». То есть упаковывайте то, что переиспользуется в отдельные пакеты и релизьте это через любимый пакетный менеджер, версионируя по SemVer.

2 принцип – CCP (Common Closure Principle)

«Classes that change together are packaged together — изменение в пакете должно затрагивать весь пакет». Этот принцип очень похож на SOLID-ский OCP. Классы, которые изменяются по одной и той же причине, должны упаковываться в один пакет. Что логично.

Нормальный пример: адаптеры. Библиотека, допустим, кеш. Если мы запихиваем в один пакет тучу адаптеров: для файлов, memcached, Redis, то при попытке изменить один какой-то адаптер мы нарушаем два принципа. Во-первых, принцип REP (начинаем релизить один из адаптеров, а релизить приходится все). А во-вторых — принцип CCP. Это когда классы для адаптера под Redis изменяются, а все остальные адаптеры в пакете —нет.

3 принцип – CRP (Common Reuse Principle)

«Classes that are used together are packaged together — Пакеты должны быть сфокусированными. Использоваться должно всё». То есть классы, которые используются вместе — упаковываем вместе. Проверочное правило здесь такое: смотрим, используется ли в нашем софте всё из того пакета, который к нему подключен. Если используется чуть-чуть, значит, скорее всего, пакет спроектирован неверно.

Эти три принципа дают понимание, как пакеты дизайнить. И казалось бы, нормально делай — нормально будет. Однако реальность сурова, и я сейчас объясню — почему. Вспомним треугольник от Артемия Лебедева, который вершины «быстро», «дёшево» и «качественно» обозначил несколько другими словами. Такой же треугольник нарисовали и для пакетных принципов в Институте Макса Планка:

Получается, эти принципы конфликтуют, и в зависимости от того, какие стороны треугольника мы выбираем, вылезают соответствующие косяки:

Теперь переходим к принципам использования.

4 принцип – ADP (Acyclic Dependencies Principle)

«The dependency graph of packages must have no cycles — Если есть циклические зависимости, то проблема вызывает лавину». Если есть циклы, то есть зависимость пакета зависит от самого пакета прямо или косвенно, то косяк в одном пакете вызывает лавину во всех остальных пакетах, и ломается абсолютно всё. К тому же, такие пакеты очень тяжело релизить.

Поэтому надо проверять, есть ли циклы. Для этого необходимо строить направленный граф зависимостей и смотреть на него. Руками это делать не очень удобно, поэтому для PHP есть библиотека clue/graph-composer, которой скармливаешь пакет, и она строит гигантский граф со всеми зависимостями. Смотреть на это, конечно, невозможно, поэтому надо зайти в PR#45, зачекаутить его и выбрать возможность исключать зависимости, которые не интересны. Допустим, если вы пишите фреймворк, то вам скорее всего интересны зависимости на свои пакеты, а чужие — не так сильно, ведь свои косяки поправить можем, чужие — тяжелее. И получается вот такой граф:

Если мы видим — как здесь — что циклических зависимостей нет, то всё отлично. Если есть, надо исправлять. Чем меньше зависимостей, тем проще.

Как разорвать цикл?

5 принцип – SDP (Stable Dependencies Principle)

Это принцип стабильных зависимостей: «Depend in the direction of stability — Не получится строить стабильное на нестабильном». Нестабильность считается так:

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

6 принцип – SAP (Stable Abstraction Principle)

Принцип стабильных абстракций гласит «A package abstractness should increase with stability — Стабильные пакеты абстрактны / Гибкие конкретны». То есть абстрактность должна возрастать со стабильностью. Стабильность здесь — то, как часто нам приходится менять части пакета: классы, интерфейсы, или что-либо ещё. Абстрактные пакеты должны быть стабильны, чтобы безболезненно на них завязываться. В примере с тем же кэшем пакет с интерфейсом будем сверхстабильным, потому что менять интерфейс, про который мы договорились и хорошо над ним подумали — скорее всего, не придётся. Если мы, конечно, абстрагируем не СУБД.

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

Можно ли измерить абстрактность?

Конечно. Абстрактность — это число абстрактных классов и интерфейсов в пакете, деленное на общее число классов и интерфейсов в этом самом пакете:


Еще есть такой полезный показатель, как D-метрика, в которой по вертикали — нестабильность, а по горизонтали — абстрактность. По двум зонам — вверху справа и внизу слева — мы можем понять:

Линия посередине называется главной линией, и если классы и интерфейсы попадают на неё или выстраиваются вдоль — это тот случай, когда всё отлично. По сути, D-метрика — это дистанция от главной линии, поэтому 0 в этом случае — это хорошо, а 1 — плохо. Но, как правило, ни то, ни другое не случается — значения плавают в диапазоне от 0 до 0,9-0,7. Считается метрика так:


Для PHP есть 2 инструмента для того, чтобы посмотреть метрику своих пакетов:

Как и SOLID, все эти дополнительные принципы и метрики — не догма, но могут быть весьма полезными.

Резюме

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

Данные принципы же позволяют не скатываться в монолит или в left-pad из npm. С left-pad была в свое время история — его создали для добавления символа в конце строки, так как в JavaScript есть традиция дробить пакеты вообще в пыль. А потом на этот пакет завязалось практически всё — вплоть до пакетных менеджеров и самых крутых фреймворков. В какой-то момент автор обиделся на всех и выпилил left-pad из системы — после чего, как вы понимаете, сломалось всё. Рассмотренные принципы, в том числе, позволяют уменьшить вероятность такого сценария.

Единственная конференция по PHP в России PHP Russia 2021 пройдет в Москве 28 июня. Первые доклады уже приняты в программу!

Купить билеты можно тут.

Хотите получить материалы с предыдущей конференции? Подписывайтесь на нашу рассылку.

Источник

Понравилась статья? Поделиться с друзьями:

Не пропустите наши новые статьи:

  • что такое пакет windows plus
  • что такое пакет sdk для windows 10
  • Что такое пакет linux
  • Что такое пайплайн в программировании
  • что такое пагинация в программировании

  • Операционные системы и программное обеспечение
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии