Вступление
Понимание соглашений о структурировании приложения Dart помогает определить и разделить проблемы сущностей и, таким образом, подготовить дорогу к оптимальной архитектуре приложения.
Для достижения этого критически важно базовое понимание пакетов, библиотек и механизма импорта.
Dart разработан с учетом поддержки модульности, а в Dart это достигается с помощью пакетов, библиотек и классов.
В этой статье мы разделим разницу между библиотеками и пакетами, а также объясним, как их импортировать.
Библиотека:
В программировании библиотека - это набор предварительно скомпилированных подпрограмм, которые программа может использовать. Процедуры, иногда называемые модулями.
- webopedia.com
⇒ каждое приложение Dart представляет собой библиотеку, даже если оно не использует каталог lib
.
Библиотеки в Dart не являются исключением: при структурировании кода вы можете встретить набор инструкций по программированию (функции, константы, классы…), которые разделяют тот же интерес.
Библиотека - это возможность подумать при структурировании кода, соответственно предоставляя API.
В: Библиотеки, мне нужно их использовать?
О: Да! Фактически, библиотеки являются важной концепцией объектно-ориентированного программирования, поскольку они помогают минимизировать тесную связь и сделать код удобным для сопровождения.
Пример: dart:math
library - это модуль, который содержит математические константы и функции, а также генератор случайных чисел.
Создание собственных библиотек
- Объявите библиотеку
Чтобы объявить библиотеку в Dart, используйте ключевое слово library
, за которым следует имя библиотеки и точка с запятой.
Пример:
library trigonometric_functions;
2. Импортируйте файлы, которые будет использовать библиотека.
Наша библиотека может опираться на логику кода, существующую в других библиотеках. Импорт библиотек в нашу библиотеку возможен в Dart с помощью ключевого слова import
.
Пример: основываясь на приведенном выше примере, мы получаем
library trigonometric_functions;
import dart:math;
3. Часть и часть директив
При создании библиотеки вы можете разделить логику кода на несколько файлов. Это возможно с помощью директив part
и part of
.
Пример:
library trigonometric_functions;
import dart:math;
part 'cos.dart';
part 'sin.dart';
cos.dart
и sin.dart
- оба файла, содержащие логику кода для функций косинуса и синуса соответственно. Таким образом, мы можем разделить логику кода библиотеки trigonometric_functions на несколько файлов.
Nextstep должен указать, частью какой библиотеки являются исходные файлы cos.dart
и sin.dart
! ;)
внутри cos.dart
файла:
part of 'trigonometric_functions';
//cos.dart source code
внутри файла sin.dart
:
part of 'trigonometric_functions';
//sin.dart source code
Примечание: в этом примере оба файла cos.dart
и sin.dart
находятся в той же папке, что и файл библиотеки trigonometric_functions
. Как правило, вы указываете относительный путь к исходным файлам, на которые вы полагаетесь.
Примечание: объявление библиотеки, импорт и исходные файлы, которые являются частью библиотеки, должны находиться вверху, а логика библиотеки появляется только после.
Примечание. В рекомендациях Dart рекомендуется избегать директив part
и part of
и вместо этого разбивать код на более мелкие библиотеки. В приведенном выше примере мы создадим библиотеки для sin.dart
и cos.dart
и импортируем их внутри trigonometric_functions
. Однако директивы part
и part of
имеют то преимущество, что этот импорт опускается и ограничивается только trigonometric_functions
.
Встроенные и настраиваемые библиотеки
В Dart есть 2 вида библиотек:
1. встроенные библиотеки
2. пользовательские библиотеки
встроенные библиотеки
встроенные библиотеки - это библиотеки, включенные в пакет dart
Пример:
dart:core
Основная библиотека определяет
встроенные типы, коллекции и другие основные функции для каждой программы Dart. Эта библиотека автоматически импортируется.
пользовательские библиотеки
пользовательские библиотеки бывают двух видов
- внешние библиотеки: библиотеки, импортированные из внешних пакетов.
- локальные библиотеки: библиотеки, которые определены внутри пакета точки входа.
Упаковка
Пакет в Dart - это каждый каталог, содержащий файл pubspec.yaml
pubspec.yaml
Pubspec - это файл с именем pubspec.yaml
, он должен находиться внутри каталога пакета на верхнем уровне.
Pubspec.yaml содержит метаданные о нашем пакете, такие как _34 _, _ 35_, description
, и другие зависимости пакетов, которые использует наше приложение.
Самый простой pubspec.yaml
file - это файл, в котором указано имя пакета
⇒ Каждое приложение в dart - это пакет, потому что он должен иметь pubspec.yaml
файл
В Dart есть два вида пакетов.
- пакет приложений
- пакет библиотеки
⇒ В файле pubspec.yaml
нет специального обозначения, указывающего, является ли пакет приложением или пакетом библиотеки.
паб
pub
- это менеджер пакетов. Это менеджер пакетов Dart.
паб получить
Если у вас есть файл pubspec, вы можете получить зависимости, определенные в этом pubspec, выполнив команду pub get
внутри каталога пакета, в котором определен pubspec.
пакет библиотеки
Пакет, от которого могут зависеть другие пакеты. Пакеты библиотеки могут иметь зависимости от других пакетов и сами могут быть зависимостями.
что делает пакет библиотеки
⇒ рядом с файлом pubspec.yaml
папка lib
является обязательной в пакете библиотеки и должна находиться на верхнем уровне каталога пакета.
Затем код библиотеки должен быть расположен внутри каталога lib, чтобы он был общедоступным для других пакетов.
Вы можете создать любую иерархию в папке lib
. По соглашению код реализации помещается в папку lib/src
.
Обратите внимание: поскольку это вложенная папка, файлы внутри нее считаются личными для других пакетов.
Итак, у вас получилось что-то вроде этого:
структурирование пакета библиотеки
пакет приложений
Пакет, который не предназначен для использования в качестве библиотеки. Пакеты приложений могут зависеть от других пакетов, но никогда не зависят от самих себя.
Хотя пакеты приложений не предназначены для использования в качестве библиотек в других пакетах по соглашению, они по-прежнему имеют папкуlib
и папку lib/src
, где существует код реализации.
Точка входа в дротик
Точка входа в Dart - это .dart
файл, содержащий функцию main()
.
Пакет точек входа
Также называемый корневым пакетом обычно является пакет приложения, это пакет с точкой входа Dart, который будет запущен. В зависимости от пакетов также могут быть точки входа Dart, но в этом контексте пакет точки входа - это пакет с точкой входа Dart, предназначенной для запуска.
Каталог точек входа
Каталог точек входа - это каталог, который может содержать точки входа Dart.
Pub
имеет белый список каталогов, которые могут быть каталогами точек входа.
benchmark
, bin
, example
, test
, tool
и web
Любая точка входа в Dart внутри этих каталогов будет автоматически обнаружена pub
. Точка входа Dart также может находиться во вложенной папке в этих каталогах. Однако папка bin
является исключением, поскольку точка входа Dart должна существовать внутри самой папки bin
, а не быть вложенной.
⇒ поэтому вы чаще всего найдете файл main.dart
в одном из упомянутых выше каталогов.
Примечания:
- в отличие от пакетов библиотеки, пакет приложения требует для выполнения
main
файл, поэтому мы добавили файлmain.dart
в каталогbin
. В качестве альтернативы файлmain.dart
может находиться, среди прочего, в папкеexample
или в папкеlib
. - Мы опустили общедоступные файлы в каталоге
lib
, поскольку этот пакет является пакетом приложения.
Как работает импорт
Зависимость
Зависимость - это еще один пакет, который нужен вашему пакету для работы.
Есть 2 вида зависимостей:
- немедленная зависимость:
Зависимость, которую ваш пакет напрямую использует. Зависимости, которые вы указываете в своей pubspec, являются непосредственными зависимостями вашего пакета ». - транзитивная зависимость:
Зависимость, которую ваш пакет использует косвенно, потому что этого требует одна из его зависимостей. Если ваш пакет зависит от A, который, в свою очередь, зависит от B, который зависит от C, тогда A является «непосредственной зависимостью, а B и C - транзитивными ».
Как импортировать библиотеки в Dart
3 вида импорта в Dart
1: импорт библиотеки из основного пакета dart
Чтобы импортировать библиотеки из пакета dart core, используйте префикс dart:
в имени пути, за которым следует имя библиотеки.
Пример:
import 'dart:core';
2: импорт библиотеки с использованием относительного пути
Чтобы импортировать библиотеки с использованием их относительного пути, используйте ключевое слово import
, за которым следует путь в кавычках.
import '../foo/a.dart';
Пример из документации Dart.
В левой части дерева мы видим, что и b.dart
, и a.dart
находятся внутри папки lib
, а файлb.dart
импортирует файл a.dart
, используя его относительный путь.
3: импорт библиотеки с использованием префикса package:, за которым следует относительный путь
Чтобы импортировать библиотеки из пакетов, используйте префикс package:
, за которым следует путь в кавычках.
Пример:
import 'package:my_package/foo/a.dart';
Usecase: этот стиль импорта используется для импорта библиотек из внешних пакетов, но также может использовать этот стиль для импорта библиотек из вашего собственного пакета.
В приведенном выше примере диаграммы мы импортировали файл a.dart
в файл main.dart
, используя префикс package:
.
Примечание: мы могли бы использовать импорт относительного пути без префикса package:
, а оператор импорта был бы эквивалентен
import '../lib/foo/a.dart';
Однако в этом случае более элегантно использовать префикс package:
, за которым следует имя пакета, поскольку импортированный файл a.dart
находится внутри каталога lib
, а импортируемый файл main.dart
- нет.
⇒ package:package_name
эквивалентно абсолютному пути /lib
Примечание: очевидно, что мы можем использовать префикс package:
, когда и импортируемый файл, и импортированный файл находятся в каталоге lib
. В приведенном выше примере, когда b.dart
импортирует a.dart
, импорт будет эквивалентен
import 'package:my_package/foo/a.dart';
Следующий
Во второй части мы рассмотрим
1. пространства имен: ключевые слова show, hide и as
2. экспорт
3. условный импорт
4. обычное структурирование библиотек
5. обычное структурирование пакетов