Что такое Репозитории (repo) в Cydia, список полезных репозиториев? Что такое репозитории и для чего они служат в Linux? Репозиторий данных.
Repository commonly refers to a storage location, often for safety or preservation.
- Wikipedia
Вот как Википедия описывает репозиторий. Так уж случилось, что в отличие от некоторых других жаргонных словечек, с которыми мы имеем дело, этот термин прекрасно передает свою суть. Репозиторий представляет собой концепцию хранения коллекции для сущностей определенного типа.
Репозиторий как коллекция
Вероятно, наиболее важным отличием репозиториев является то, что они представляют собой коллекции объектов. Они не описывают хранение в базах данных или кэширование или решение любой другой технической проблемы. Репозитории представляют коллекции. Как вы храните эти коллекции - это просто деталь реализации.Я хочу внести ясность в этот вопрос. Репозиторий - это коллекция. Коллекция, которая содержит сущности и может фильтровать и возвращать результат обратно в зависимости от требований вашего приложения. Где и как он хранит эти объекты является ДЕТАЛЬЮ РЕАЛИЗАЦИИ.
В мире PHP мы привыкли к циклу запрос/ответ, который оканчивается смертью процесса. Все, что пришло извне и не сохранилось - ушло навсегда, в этой точке. Так вот, не все платформы работают именно так.
Хорошим способом понять как работают репозитории является представление вашего приложения постоянно работающим, в этом случае все объекты остаются в памяти. Вероятность критических сбоев и реакцию на них в этом эксперименте можно пренебречь. Представьте, что у вас есть Singleton-экземпляр репозитория для сущностей Member , MemberRepository .
Затем создайте новый объект Member и добавьте его в репозиторий. Позже, вы запросите у репозитория все элементы, хранящиеся в нем, таким образом вы получите коллекцию, которая содержит этот объект внутри. Возможно вы захотите получить какой-то конкретный объект по его ID, это также возможно. Очень легко представить себе, что внутри репозитория эти объекты хранятся в массиве или, что еще лучше, в объекте-коллекции.
Проще говоря, репозиторий - это особый вид надежных коллекций, которые вы будете использовать снова и снова, чтобы хранить и фильтровать сущности.
Взаимодействие с Репозиторием
Представьте, что мы создаем сущность Member . Мы приводим объект к необходимому состоянию, затем запрос заканчивается и объект исчезает. Пользователь пытается авторизоваться в нашем приложении и не может. Очевидно, что нам необходимо сделать этот объект доступным и для других частей приложения. $member = Member::register($email, $password);
$memberRepository->save($member);
Теперь мы можем получить доступ к объекту позже. Примерно так:
$member = $memberRepository->findByEmail($email);
// or
$members = $memberRepository->getAll();
Мы можем хранить объекты в одной части нашего приложения, а затем извлекать их из другой.
Должны ли репозитории создавать сущности?
Вы можете встретить такие примеры: $member = $memberRepository->create($email, $password);
Я видел множество аргументов приводящихся в пользу этого, но совершенно не заинтересован в подобном подходе.
Прежде всего, репозитории - это коллекции. Я не уверен в том, зачем коллекция должна быть коллекцией и фабрикой. Я слышал аргументы вроде «если обращаться удобнее так, то почему бы не повесить обработчик на подобные действия» ?
На мой взгляд, это анти-паттерн. Почему бы не позволить классу Member , иметь свое собственное понимание как и зачем создается объект или почему бы не сделать отдельную фабрику для создания более сложных объектов?
Если мы относимся к нашим репозиториям как к простым коллекциям, так значит и не нужно нагружать их лишним функционалом. Я не хочу классов коллекций, которые ведут себя как фабрики.
В чем выгода использования репозиториев?
Основное преимущество репозиториев - это абстрактный механизм хранения для коллекций сущностей.Предоставляя интерфейс MemberRepository мы развязываем руки разработчику, который уже сам решит как и где хранить данные.
Class ArrayMemberRepository implements MemberRepository { private $members = ; public function save(Member $member) { $this->members[(string)$member->getId()] = $member; } public function getAll() { return $this->members; } public function findById(MemberId $memberId) { if (isset($this->members[(string)$memberId])) { return $this->
Class RedisMemberRepository implements MemberRepository {
public function save(Member $member) {
// ...
}
// you get the point
}
Таким образом, большинство наших приложений знает только абстрактное понятие MemberRepository и его использование может быть отделено от фактической реализации. Это очень раскрепощает.
К чему относятся репозитории: Domain или Application Service Layer?
Итак, вот интересный вопрос. Во-первых, давайте определим, что Application Service Layer - это многоуровневая архитектура, которая отвечает за специфические детали реализации приложения, такие как целостность базы данных, и различные реализации работы с интернет-протоколами (отправка электронной почты, API) и др.Определим термин Domain Layer как слой многоуровневой архитектуры, которая отвечает за бизнес-правила и бизнес-логику.
Куда же попадет репозиторий при таком подходе?
Давайте посмотрим на нашем примере. Вот код, написанный ранее.
Class ArrayMemberRepository implements MemberRepository {
private $members = ;
public function save(Member $member) {
$this->members[(string) $member->getId()] = $member;
}
public function getAll() {
return $this->members;
}
public function findById(MemberId $memberId) {
if (isset($this->members[(string)$memberId])) {
return $this->members[(string)$memberId];
}
}
}
В этом примере я вижу много деталей реализации. Они, несомненно, должны входить в слой приложения
А теперь давайте удалим все детали реализации из этого класса…
Class ArrayMemberRepository implements MemberRepository {
public function save(Member $member) {
}
public function getAll() {
}
public function findById(MemberId $memberId) {
}
}
Хм… это начинает выглядеть знакомо… Что же мы забыли?
Возможно, получившийся код напоминает вам это?
Interface MemberRepository {
public function save(Member $member);
public function getAll();
public function findById(MemberId $memberId);
}
Это означает, что интерфейс находится на границе слоев. и на самом деле может содержать доменно-специфические концепты, но сама реализация не должна этого делать.
Интерфейсы репозиториев принадлежат к слою домена. Реализация же относятся к слою приложения. Это означает, что мы свободны при построении архитектуры на уровне доменного слоя без необходимости зависеть от слоя сервиса.
Свобода смены хранилищ данных
Всякий раз, когда вы слышите чей-то разговор о концепции объектно-ориентированного дизайна, вы, наверное, могли слышать что-то вроде "… и у вас есть возможность поменять одну реализацию хранения данных на другую в будущем..."По-моему, это не совсем правда… я бы даже сказал, что это очень плохой аргумент. Самой большой проблемой объяснения концепции репозиториев является то, что сразу напрашивается вопрос «вы действительно хотите это делать?» . Я НЕ хочу чтобы подобные вопросы влияли на использование паттерна репозитория.
Любое достаточно хорошо спроектированное объектно-ориентированное приложение автоматически подходит под приведенное преемущество. Центральной концепцией ООП является инкапсуляция. Вы можете предоставить доступ к API и скрыть реализацию.
Ведь вы же на самом деле не будете переключаться с одного ORM на другой и обратно. Но даже если вы захотите так делать, то, по крайней мере, у вас будет возможность сделать это. Однако, замена реализации репозитория будет огромным плюсом при тестировании.
Тестирование при использовании паттерна «Репозиторий»
Ну, тут все просто. Давайте предположим, что у вас есть объект, который обрабатывает что-то вроде регистрации участников…Class RegisterMemberHandler {
private $members;
public function __construct(MemberRepository $members) {
$this->members = $members;
}
public function handle(RegisterMember $command) {
$member = Member::register($command->email, $command->password);
$this->members->save($member);
}
}
Во время очередной операции, я могу взять экземпляр DoctrineMemberRepository . Однако, во время тестирования легко можно заменить его на экземпляр ArrayMemberRepository. Они оба реализуют один и тот же интерфейс.
Упрощенный пример теста может выглядеть примерно так…
$repo = new ArrayMemberRepository;
$handler = new RegisterMemberHandler($repo);
$request = $this->createRequest(["email" => "[email protected]", "password" => "angelofdestruction"]);
$handler->handle(RegisterMember::usingForm($request));
AssertCount(1, $repo->findByEmail("[email protected]"));
В этом примере мы тестируем обработчик. Нам не нужно проверять корректность хранения данных репозитория в БД (или еще где). Мы тестируем конкретное поведение этого объекта: регистрируем пользователя на основе данных формы, а затем передаем их в репозиторий.
Коллекция или Состояние
В книге Implementing Domain-Driven Design Vaughn Vernon делает различие между типами репозиториев. Идея коллекцио-ориентированного репозитория (ориг. - collection-oriented repository) в том, что работа с репозиторием идет в памяти, как с массивом. Репозиторий, ориентированный на хранение состояний (ориг. - persistence-oriented repository) содержит в себе идею, что в нем будет какая-то более глубокая и продуманная система хранения. По сути различия лишь в названиях. // collection-oriented
$memberRepository->add($member);
// vs persistence-oriented
$memberRepository->save($member);
Замечу, что это лишь мое мнение и пока что я придерживаюсь именно его в вопросах использования репозиториев. Однако, хотел бы предупредить, что возможно могу передумать. В конце-концов, я сосредотачиваюсь на них как на коллекциях объектов с теми же обязанностями, что и у любого другого объекта-коллекции.
Дополнительная информация
создал проект на Github о репозиториях на который, безусловно, стоит посмотреть. Внутри вы найдете примеры работы с хранением в памяти и файлах.Итоги
Я считаю, что…- … важно дать репозиториям сингулярную задачу функционировать как коллекция объектов.
- … мы не должны использовать репозитории для создания новых экземпляров объектов.
- … мы должны избегать использования репозиториев как способа перехода от одной технологии к другой, так как они имеют очень много преимуществ, от которых трудно отказаться.
Если у вас есть вопросы или если ваше мнение отличается от моего, пожалуйста, пишите комментарии ниже.
Как всегда, я намерен обновлять статью, чтобы синхронизировать ее с моим текущим мнением.
Персональные архивы пакетов или PPA (Personal Package Archives) - это и есть репозиторий (сервер-хранилище).
Репозиторий, хранилище - место, где хранятся и поддерживаются какие-либо данные. Чаще всего данные в репозитории хранятся в виде файлов, доступных для дальнейшего распространения по сети. Репозитории подразделяются на официальные и неофициальные. Большинство дистрибутивов Linux
, имеют официальные репозитории.
Официальные репозитории.
Официальные репозитории создаются разработчиками дистрибутива для поддержания в актуальном и безопасном состоянии системы. Если вы откроете в Ubuntu текстовый файл но адресу: /etc/apt/sources.list , то найдёте в нём следующие строки:
Закомментированные строки (строки, перед которыми стоит знак решётки (# ), считаются закомментированными), как правило не читаются системой, а служат для пояснения администратору системы (администратор системы - пользователь, который во время установки системы ввёл свой пароль) к действующему официальному репозиторию или той строке, которая раскомментирована (без знака решётки - #) и следует за описанием.
Для управления официальными репозиториями предназначена программа Программы и обновления (Источники приложений), в вкладке Программное обеспечение Ubuntu :
Все изменения: обновление пакетов программ; изменения в системе безопасности; обновление ядра, исправление ошибок и т.п., внесённые в данные репозитории разработчиками Ubuntu , пользователь получает через штатное обновление дистрибутива - Обновление приложений . Периодически система автоматически просматривает все прописанные в ней репозитории и скачивает новые индексы.
Приложения отображённые в Менеджере приложений Ubuntu также находятся в официальных репозиториях, а это значит что они прошли проверку на совместимость и безопасность, и могут быть в любое время установлены в системе (по мере необходимости).
Неофициальные репозитории
К неофициальным репозиториям относятся хранилища файлов пакета/пакетов, созданные обычными пользователями, так называемые Собственные репозитории .
Для чего создаются Собственные (неофициальные) репозитории ?
Предположим вы хотите установить дополнительно какую-то программу из Менеджера программ Ubuntu
, но в нём более поздняя версия для установки, чем на официальном сайте программы или этой программы просто нет в Менеджере программ
, но она существует.
Один из продвинутых пользователей Linux
создаёт свой собственный репозиторий с актуальной версией программы, где учтены все зависимости пакета и их совместимость с системными файлами. Специально для создания собственного репозитория создана площадка/ресурс под названием launchpad.net .
Как установить программу из Неофициального репозитория ?
Сделать это можно как графически, так и в терминале.
1. Терминальный вариант.
Если вы являетесь новичком или просто обычным пользователем Ubuntu
, то скорее всего обратили внимание, что на сайтах подобных Compizomania
, установка приложения иногда производится с помощью терминальных команд. Для примера я выбрал установку программы i-nex
.
I-Nex -
это программа с графическим интерфейсом, позволяющая посредством вкладок просмотр информации аппаратных устройствах вашего компьютера, пдкючённых устройствах стационарного компьютера: мышь, клавиатура и т.д., а также об установленной системе, используемом ядре, оперативной памяти и многом другом.
Данной программы нет в Менеджере программ , поэтому как один из возможных способов её установки, это установка с помощью терминальных команд и подключения стороннего репозитория:
sudo add-apt-repository
sudo apt update
sudo apt install i-nex
Разберём эти команды по порядку.
Первая команда sudo add-apt-repository ppa:i-nex-development-team/daily подключает репозиторий программы (выделено красным), созданный непосредственно разработчиком.
Вторая команда sudo apt update , делает обновление системных файлов.
И третья команда sudo apt install i-nex , служит для непосредственной установки пакета i-nex .
2. Графический вариант.
Графический вариант подключения репозитория и установки программы, делает тоже самое, только "в картинках", т.е. в окнах приложений.
Прежде всего заходим на launchpad.net , вводим в поиск название программы и нажимаем кнопку Search Launchpad :
Выбираете нужный репозиторий:
Просматриваете совместимость репозитория с вашим дистрибутивом и копируете название репозитория:
Откройте Программы и обновления , вкладка Другое ПО , нажмите кнопку Добавить , в Строку APT вставьте скопированный репозиторий и Добавить источник :
После ввода пароля, добавленный сторонний репозиторий отобразится в перечне уже добавленных (если вы ранее добавляли неофициальные репозитории). Нажмите кнопку Закрыть.
И обновите системные файлы:
Остаётся последнее, установить саму программу:
sudo apt install i-nex
Примечание . Все подключёные Неофициальные репозитории отображаются в приложении Программы и обновления , в вкладке Другое ПО . Независимо от того, как вы их подключали, посредством терминала или графически. А также в папке по адресу: /etc/apt/sources.list.d .
Заключение.
Официальные репозитории более стабильны и надёжны, чем Неофициальные , т.к. создаются непосредственно разработчиками дистрибутива, где учтены все необходимые зависимости пакета/пкетов и их совместимость с системными файлами.
Неофициальный репозиторий может быть создан как разработчиками того или иного приложения, так и обычным продвинутым пользователем с благими намерениями для установки и дальнейшего обновления программы.
Но в то же время Неофициальный репозиторий может иметь "подводные камни", которые порой приводят к сбоям в системе.
Отчего это происходит?
1
. Прежде всего, несмотря на благие намерения пользователя, создавшего репозиторий, он не всегда может быть компетентен в вопросах совместимости и безопасности создаваемых пакетов в репозитории, что приводит порой к конфликту пакетов и сбою в системе.
2.
Создатель собственного (неофициального) репозитория программы может просто забросить свой проект, потешив своё самолюбие, победой над собой. И тогда в последующих версиях дистрибутива вы не сможете устанавливать программы из этого репозитория.
Будьте осторожны с Неофициальными репозиториями и подключайте только те, которые проверены сообществом и вами. А для установки программного обеспечения лучше пользоваться Менеджером программ , хотя там не всегда можно найти актуальную версию программы.
Открываем менеджер пакетов Synaptic, заходим в настройки, выбираем репозитории.
В открывшемся окне несколько вкладок с типами репозиториев:
Main - основная ветка - стабильное официально поддерживаемое Canonical ПО
Restricted - официально поддерживаемое ПО распространяемое не под лицензией GPL
Universe - программы, поддерживаемые сообществом Ubuntu
Multiverse - ветка проприетарного программного обеспечения
В зависимости от дистрибутива линукса эти окна немного могут немного различаться, например в Mint выглядит так.
Для добавления репозитория в Ubuntu перейдите на вкладку другое ПО на этой вкладке вы можете видеть весь список репозиториев Ubuntu которые были подключены к системе:
Чтобы иметь доступ к дополнительным программам рекомендуется подключить сторонний репозиторий партнеров Canonical. Для этого просто поставьте напротив него галочку.
Для добавления репозитория Ubuntu нажмите кнопку Добавить:
Здесь в единственном поле нужно ввести apt строку репозитория и нажать кнопку добавить источник.
Apt строка репозитория имеет такой синтаксис:
deb http://адрес_репозитория версия_дистрибутива ветки
Например:
deb http://ua.archive.ubuntu.com/ubuntu/ xenial main restricted
deb https://apt-mo.trafficmanager.net/repos/dotnet/ trusty main
Чтобы добавить в командной строке, достаточно выполнить команду:
sudo add-apt-repository "deb адрес репозитория ветка main"
Например:
sudo add-apt-repository "deb http://mirror.yandex.ru/ubuntu/ trusty main"
Основные репозитории для Ubuntu, Mint и им подобных
Ualinux
Данный репозиторий могут использовать не только пользователи Ubuntu, но так же и пользователи Kubuntu, Xubuntu, Lubuntu и других систем, таких как LinuxMint, Runtu и д.р.
Интернет программы
sudo add-apt-repository ppa:chromium-daily/stable
wget https://dl.google.com/linux/direct/google-chrome-stable_current_i386.deb
sudo dpkg -i google-chrome-stable_current_i386.deb
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
sudo add-apt-repository "deb http://deb.opera.com/opera/ stable non-free"
wget -O - http://deb.opera.com/archive.key | sudo apt-key add -
sudo add-apt-repository ppa:mozillateam/firefox-next
Twitter-клиент Hotot
Sudo add-apt-repository ppa:hotot-team
Это репозиторий замечательного твиттер клиента Turpial
sudo add-apt-repository ppa:effie-jayx/turpial
Мультимедиа
sudo add-apt-repository ppa:videolan/stable-daily
MPV (ответвление mplayer)
sudo add-apt-repository ppa:mc3man/mpv-tests
sudo add-apt-repository ppa:mc3man/trusty-media
Lightworks - мощная программа для монтажа теперь доступна под Ubuntu
VkAudioSaver: аудиоплеер для скачивания и прослушивания музыки из ВКонтакта
Pepperflash (замена flash-player для Chromium)
sudo add-apt-repository ppa:skunk/pepper-flash
sudo apt-get update && sudo apt-get install pepflashplugin-installer
После установки вам нужно указать Chromium, что нужно пользоваться Pepper Flash Player. Для этого отредактируйте файл запуска браузера. Введите следующую команду:
sudo gedit /etc/chromium-browser/default
И в самом конце файла вставьте следующую строчку:
./usr/lib/pepflashplugin-installer/pepflashplayer.sh
Cinelerra - видеоредактор
sudo add-apt-repository ppa:cinelerra-ppa/ppa
Аудиоплеер наподобие Winamp.
sudo add-apt-repository ppa:alexey-smirnov/deadbeef
Кодеры-декодеры
Mobile Media Converter
Простой интуитивно понятный интерфейс, множество поддерживаемых форматов.
Программа очень простая, мало настроек и предустановок.
sudo add-apt-repository ppa:paul-climbing/ppa
sudo apt-get install winff
sudo add-apt-repository ppa:nilarimogard/webupd8
sudo apt-get update
sudo apt-get install transmageddon
Skype Call Recorder
Запись звонков Skype. Программа кроссплатформенная.
sudo add-apt-repository ppa:dajhorn/skype-call-recorder
Запись экрана с множеством возможностей.
sudo add-apt-repository ppa:maarten-baert/simplescreenrecorder
sudo apt-get update
sudo apt-get install simplescreenrecorder
Драйвера
официальный репозиторий графических драйверов Intel
sudo add-apt-repository "deb https://download.01.org/gfx/ubuntu/14.04/main trusty"
sudo add-apt-repository ppa:ubuntu-x-swat/x-updates
Под различные ОС можно скачать .
sudo add-apt-repository ppa:alexx2000/doublecmd
Распознавание текста
GImageReader и Tesseract
sudo add-apt-repository ppa:gezakovacs/tesseract
sudo add-apt-repository ppa:sandromani/gimagereader
Cuneiform и Yagf
sudo add-apt-repository ppa:alex-p/notesalexp
Это репозиторий, в котором есть графическая оболочка для Cuneiform - программа Yagf. Служит для распознания текста в Linux.
Настройка
Ezame - новый редактор меню для Unity
sudo add-apt-repository ppa:caldas-lopes/ppa
sudo apt-get update
sudo apt-get install gksu ezame
sudo add-apt-repository ppa:tualatrix/ppa
Sudo add-apt-repository ppa:danielrichter2007/grub-customizer
Графическое приложение для конфигурации Grub/Burg, чтобы не копаться вручную в их многочисленных настройках в /etc.
Различные дополнения
Для самых крайних версий
sudo add-apt-repository ppa:kde3-maintainers/trinity-svn-nightly
Темы, иконки
sudo add-apt-repository ppa:tiheum/equinox
sudo apt-get install faenza-icon-theme faience-icon-theme faience-theme
sudo add-apt-repository ppa:noobslab/icons
sudo apt-get install awoken-icon-theme mint-x-icons malys-ex malys-uniblack malys-uniblue acyl-icons darkenza mac-x-lion-reloaded nitrux-icons meliaesvg-icons piratunbu-icons azenis-green-icons nouvegnome-color nouvegnome-gray fs-icons hi-lights-icons matrilineare
sudo add-apt-repository ppa:upubuntu-com/icons
sudo apt-get install azenis-icons betelgeuse-icons candy-icons faenk-icons gxiria-icons hilights-icons hydroxygen-icons kalahari-icons magog-white-icons mx-icons propheticon13 sphere-icons
Работа с текстом
Libreoffice
sudo add-apt-repository ppa:vincent-c/cherrytreeЭто репозиторий древовидного иерархического текстового редактора Cherry Tree.
sudo add-apt-repository ppa:pdfshuffler/ppa
Просмотрщик PDF
sudo add-apt-repository ppa:ed10vi86/ppa
sudo add-apt-repository ppa:pdfmod-team/ppa
sudo add-apt-repository ppa:mystic-mirage/komodo-edit
Графика
sudo add-apt-repository ppa:otto-kesselgulasch/gimp
Прочие
sudo add-apt-repository ppa:ubuntu-wine/ppa
sudo add-apt-repository ppa:stebbins/handbrake-releases
sudo add-apt-repository ppa:colingille/freshlight
sudo add-apt-repository ppa:chris-lea/node.js
Docky
sudo add-apt-repository ppa:docky-core/ppa
Java
sudo add-apt-repository ppa:webupd8team/java
SVN
sudo add-apt-repository ppa:svn/ppa
Список репозиториев ppa ubuntuupdates.org
Atareao Atareao |
Atom |
Banshee Team |
Brightbox Ruby NG Experimental |
Cairo-dock-team |
Canonical Kernel Team |
Canonical Partner |
Cassandra |
Chris Lea Nodejs |
Chromium Stable Channel |
Conky Companions |
Deluge-team |
Docker |
Docky |
Drizzle Developers |
Dropbox |
Ehoover Compholio Netflix |
EugeneSan |
Extras |
FerramRoberto VLC |
Firefox Aurora |
Flexiondotorg Java |
Flexiondotorg Shotwell |
FreeNX Stable |
FreeNX Testing |
Gdm2setup |
GetDeb Apps |
GetDeb Games |
Gloobus-dev Gloobus Preview |
Gnome 3 |
Gnome Shell |
Google Chrome |
Google Earth |
Google Music |
Google Stable Non Free |
Google Talk Plugin |
Google Testing Non Free |
Gwendal Le Bihan Dev Cinnamon Stable |
Handbrake releases |
Handbrake Snapshots |
Indicator-multiload daily |
Intel Linux Graphics |
KeePassX |
kernel-ppa |
Kubuntu-ppa Backports |
Kubuntu-ppa Beta |
Kubuntu Updates |
Lffl Wireshark |
LibreOffice |
Lucidbleed |
Mactel Support |
MariaDB 5.2 |
MariaDB 5.5 |
MariaDB Repo 5.2 |
Medibuntu Free |
Medibuntu Non Free |
Midori |
Mint Import |
Mint Main |
Mint upstream |
Mozilla Team Firefox Next |
Mozilla Team Firefox Stable |
Mozilla Team Thunderbird Stable |
Murrine Daily |
Mythtv 0.22 |
Mythtv 0.23 |
Mythtv 0.23.1 |
Mythtv 0.24 |
MythTV 0.25 |
MythTV 0.26 |
MythTV 0.27 |
MythTV 0.28 |
MythTV Testing |
nathan-renniewaldock ppa |
Nautilus Elementary |
Nginx |
Nvidia-vdpau |
Openshot-Edge |
Opera |
Percona Server with XtraDB |
Phablet Tools |
Phusion Passenger |
Pidgin |
Pipelight |
Pithos Daily |
Pitti Postgresql |
PlayOnLinux |
Postgresql |
Pratikmsinha ruby 1.9.2 |
Puppet repo |
Riak |
Scopes packagers |
Screenlets stable |
SevenMachines Flash |
Skype |
Spotify |
Sssup |
Способы установки программ в системах Windows и Linux (а также BSD) отличаются. Можно сказать, что отличается даже сама идеология установки программ. Пользователи Windows привыкли, что программа поставляется в виде установочного файла (или группы файлов). Эти файлы нужно скачать из интернета или получить на CD/DVD. Для Linux такой способ нехарактерен, хотя он тоже есть.
Собственно, репозиторий — это хранилище файлов . Система Linux подразумевает, что человек, желающий установить программу, обратится к репозиторию, в котором эта программа хранится. Делается это через терминал.
Например, я хочу установить в свой Linux Mint 17.1 программу для виртуализации Virtual Box. Я запускаю терминал и ввожу следующую команду:
sudo apt-get install virtualbox-4.3Установка должна производиться с правами суперадминистратора, поэтому мы добавляем к команде слово sudo. Терминал спрашивает у нас пароль суперадминистратора и сообщает информацию по пакетам, которые Вы собираетесь установить.
Установка VirtualBox через терминал
После согласия пользователя система начнет выкачивать нужные файлы из сетевого хранилища в Интернете. Таким образом, Вам не нужно заходить на сайт программы и скачивать установочный файл вручную.
Сам процесс установки выглядит следующим образом:
Установка VirtualBox в Linux Mint
После установки программу можно будет найти в списке других установленных программ.
VirtualBox в Linux Mint
Кто может создавать репозитории?
Кто угодно. Что касается того, из каких репозиториев берет программы операционная система, то это, в первую очередь, репозитории самой системы. Отдельные программы также имеют свои репозитории (версии программ на них, как правило, более свежие), но такие хранилища нужно добавлять в настройках операционной системы вручную. Делает это либо через Менеджер пакетов, либо через соответствующие команды в терминале.
Как видим, в моем случае в репозитории Linux Mint уже имелись файлы VirtualBox, поэтому выполнять дополнительных действий не пришлось. Что мне пришлось бы делать, если бы в репозитории системы такой программы не нашлось? Добавлять репозиторий разработчиков самой программы.
Например, найдя в меню Linux Mint пунк «Источники приложений», а там раздел «Дополнительные репозитории».
Добавление репозитория в Linux Mint
Или прописав в терминале
sudo sh -c "echo "deb http://download.virtualbox.org/virtualbox/debian trusty contrib" >> /etc/apt/sources.list"Это путь к конкретному репозиторию VirtualBox. В случае с другими программами путь будет другой. После этого обновляем кэш пакетов:
sudo apt-get updateПри добавлении ссылки на репозиторий через менеджер пакетов она так же должна быть вида deb [ссылка на репозиторий в Интернете] . Кроме того, возможно, вы заметили на скриншоте раздел с PPA-репозиториями. Им отведена .
На этом, пожалуй, всё. И помните, приручить пингвина не так сложно, как кажется.
Repository commonly refers to a storage location, often for safety or preservation.
- Wikipedia
Вот как Википедия описывает репозиторий. Так уж случилось, что в отличие от некоторых других жаргонных словечек, с которыми мы имеем дело, этот термин прекрасно передает свою суть. Репозиторий представляет собой концепцию хранения коллекции для сущностей определенного типа.
Репозиторий как коллекция
Вероятно, наиболее важным отличием репозиториев является то, что они представляют собой коллекции объектов. Они не описывают хранение в базах данных или кэширование или решение любой другой технической проблемы. Репозитории представляют коллекции. Как вы храните эти коллекции - это просто деталь реализации.Я хочу внести ясность в этот вопрос. Репозиторий - это коллекция. Коллекция, которая содержит сущности и может фильтровать и возвращать результат обратно в зависимости от требований вашего приложения. Где и как он хранит эти объекты является ДЕТАЛЬЮ РЕАЛИЗАЦИИ.
В мире PHP мы привыкли к циклу запрос/ответ, который оканчивается смертью процесса. Все, что пришло извне и не сохранилось - ушло навсегда, в этой точке. Так вот, не все платформы работают именно так.
Хорошим способом понять как работают репозитории является представление вашего приложения постоянно работающим, в этом случае все объекты остаются в памяти. Вероятность критических сбоев и реакцию на них в этом эксперименте можно пренебречь. Представьте, что у вас есть Singleton-экземпляр репозитория для сущностей Member , MemberRepository .
Затем создайте новый объект Member и добавьте его в репозиторий. Позже, вы запросите у репозитория все элементы, хранящиеся в нем, таким образом вы получите коллекцию, которая содержит этот объект внутри. Возможно вы захотите получить какой-то конкретный объект по его ID, это также возможно. Очень легко представить себе, что внутри репозитория эти объекты хранятся в массиве или, что еще лучше, в объекте-коллекции.
Проще говоря, репозиторий - это особый вид надежных коллекций, которые вы будете использовать снова и снова, чтобы хранить и фильтровать сущности.
Взаимодействие с Репозиторием
Представьте, что мы создаем сущность Member . Мы приводим объект к необходимому состоянию, затем запрос заканчивается и объект исчезает. Пользователь пытается авторизоваться в нашем приложении и не может. Очевидно, что нам необходимо сделать этот объект доступным и для других частей приложения. $member = Member::register($email, $password);
$memberRepository->save($member);
Теперь мы можем получить доступ к объекту позже. Примерно так:
$member = $memberRepository->findByEmail($email);
// or
$members = $memberRepository->getAll();
Мы можем хранить объекты в одной части нашего приложения, а затем извлекать их из другой.
Должны ли репозитории создавать сущности?
Вы можете встретить такие примеры: $member = $memberRepository->create($email, $password);
Я видел множество аргументов приводящихся в пользу этого, но совершенно не заинтересован в подобном подходе.
Прежде всего, репозитории - это коллекции. Я не уверен в том, зачем коллекция должна быть коллекцией и фабрикой. Я слышал аргументы вроде «если обращаться удобнее так, то почему бы не повесить обработчик на подобные действия» ?
На мой взгляд, это анти-паттерн. Почему бы не позволить классу Member , иметь свое собственное понимание как и зачем создается объект или почему бы не сделать отдельную фабрику для создания более сложных объектов?
Если мы относимся к нашим репозиториям как к простым коллекциям, так значит и не нужно нагружать их лишним функционалом. Я не хочу классов коллекций, которые ведут себя как фабрики.
В чем выгода использования репозиториев?
Основное преимущество репозиториев - это абстрактный механизм хранения для коллекций сущностей.Предоставляя интерфейс MemberRepository мы развязываем руки разработчику, который уже сам решит как и где хранить данные.
Class ArrayMemberRepository implements MemberRepository { private $members = ; public function save(Member $member) { $this->members[(string)$member->getId()] = $member; } public function getAll() { return $this->members; } public function findById(MemberId $memberId) { if (isset($this->members[(string)$memberId])) { return $this->
Class RedisMemberRepository implements MemberRepository {
public function save(Member $member) {
// ...
}
// you get the point
}
Таким образом, большинство наших приложений знает только абстрактное понятие MemberRepository и его использование может быть отделено от фактической реализации. Это очень раскрепощает.
К чему относятся репозитории: Domain или Application Service Layer?
Итак, вот интересный вопрос. Во-первых, давайте определим, что Application Service Layer - это многоуровневая архитектура, которая отвечает за специфические детали реализации приложения, такие как целостность базы данных, и различные реализации работы с интернет-протоколами (отправка электронной почты, API) и др.Определим термин Domain Layer как слой многоуровневой архитектуры, которая отвечает за бизнес-правила и бизнес-логику.
Куда же попадет репозиторий при таком подходе?
Давайте посмотрим на нашем примере. Вот код, написанный ранее.
Class ArrayMemberRepository implements MemberRepository {
private $members = ;
public function save(Member $member) {
$this->members[(string) $member->getId()] = $member;
}
public function getAll() {
return $this->members;
}
public function findById(MemberId $memberId) {
if (isset($this->members[(string)$memberId])) {
return $this->members[(string)$memberId];
}
}
}
В этом примере я вижу много деталей реализации. Они, несомненно, должны входить в слой приложения
А теперь давайте удалим все детали реализации из этого класса…
Class ArrayMemberRepository implements MemberRepository {
public function save(Member $member) {
}
public function getAll() {
}
public function findById(MemberId $memberId) {
}
}
Хм… это начинает выглядеть знакомо… Что же мы забыли?
Возможно, получившийся код напоминает вам это?
Interface MemberRepository {
public function save(Member $member);
public function getAll();
public function findById(MemberId $memberId);
}
Это означает, что интерфейс находится на границе слоев. и на самом деле может содержать доменно-специфические концепты, но сама реализация не должна этого делать.
Интерфейсы репозиториев принадлежат к слою домена. Реализация же относятся к слою приложения. Это означает, что мы свободны при построении архитектуры на уровне доменного слоя без необходимости зависеть от слоя сервиса.
Свобода смены хранилищ данных
Всякий раз, когда вы слышите чей-то разговор о концепции объектно-ориентированного дизайна, вы, наверное, могли слышать что-то вроде "… и у вас есть возможность поменять одну реализацию хранения данных на другую в будущем..."По-моему, это не совсем правда… я бы даже сказал, что это очень плохой аргумент. Самой большой проблемой объяснения концепции репозиториев является то, что сразу напрашивается вопрос «вы действительно хотите это делать?» . Я НЕ хочу чтобы подобные вопросы влияли на использование паттерна репозитория.
Любое достаточно хорошо спроектированное объектно-ориентированное приложение автоматически подходит под приведенное преемущество. Центральной концепцией ООП является инкапсуляция. Вы можете предоставить доступ к API и скрыть реализацию.
Ведь вы же на самом деле не будете переключаться с одного ORM на другой и обратно. Но даже если вы захотите так делать, то, по крайней мере, у вас будет возможность сделать это. Однако, замена реализации репозитория будет огромным плюсом при тестировании.
Тестирование при использовании паттерна «Репозиторий»
Ну, тут все просто. Давайте предположим, что у вас есть объект, который обрабатывает что-то вроде регистрации участников…Class RegisterMemberHandler {
private $members;
public function __construct(MemberRepository $members) {
$this->members = $members;
}
public function handle(RegisterMember $command) {
$member = Member::register($command->email, $command->password);
$this->members->save($member);
}
}
Во время очередной операции, я могу взять экземпляр DoctrineMemberRepository . Однако, во время тестирования легко можно заменить его на экземпляр ArrayMemberRepository. Они оба реализуют один и тот же интерфейс.
Упрощенный пример теста может выглядеть примерно так…
$repo = new ArrayMemberRepository;
$handler = new RegisterMemberHandler($repo);
$request = $this->createRequest(["email" => "[email protected]", "password" => "angelofdestruction"]);
$handler->handle(RegisterMember::usingForm($request));
AssertCount(1, $repo->findByEmail("[email protected]"));
В этом примере мы тестируем обработчик. Нам не нужно проверять корректность хранения данных репозитория в БД (или еще где). Мы тестируем конкретное поведение этого объекта: регистрируем пользователя на основе данных формы, а затем передаем их в репозиторий.
Коллекция или Состояние
В книге Implementing Domain-Driven Design Vaughn Vernon делает различие между типами репозиториев. Идея коллекцио-ориентированного репозитория (ориг. - collection-oriented repository) в том, что работа с репозиторием идет в памяти, как с массивом. Репозиторий, ориентированный на хранение состояний (ориг. - persistence-oriented repository) содержит в себе идею, что в нем будет какая-то более глубокая и продуманная система хранения. По сути различия лишь в названиях. // collection-oriented
$memberRepository->add($member);
// vs persistence-oriented
$memberRepository->save($member);
Замечу, что это лишь мое мнение и пока что я придерживаюсь именно его в вопросах использования репозиториев. Однако, хотел бы предупредить, что возможно могу передумать. В конце-концов, я сосредотачиваюсь на них как на коллекциях объектов с теми же обязанностями, что и у любого другого объекта-коллекции.
Дополнительная информация
everzet создал проект на Github о репозиториях на который, безусловно, стоит посмотреть. Внутри вы найдете примеры работы с хранением в памяти и файлах.Итоги
Я считаю, что…- … важно дать репозиториям сингулярную задачу функционировать как коллекция объектов.
- … мы не должны использовать репозитории для создания новых экземпляров объектов.
- … мы должны избегать использования репозиториев как способа перехода от одной технологии к другой, так как они имеют очень много преимуществ, от которых трудно отказаться.
Если у вас есть вопросы или если ваше мнение отличается от моего, пожалуйста, пишите комментарии ниже.
Как всегда, я намерен обновлять статью, чтобы синхронизировать ее с моим текущим мнением.