Что такое Репозитории (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 о репозиториях на который, безусловно, стоит посмотреть. Внутри вы найдете примеры работы с хранением в памяти и файлах.

Итоги

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

Если у вас есть вопросы или если ваше мнение отличается от моего, пожалуйста, пишите комментарии ниже.

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

Персональные архивы пакетов или 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 о репозиториях на который, безусловно, стоит посмотреть. Внутри вы найдете примеры работы с хранением в памяти и файлах.

Итоги

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

Если у вас есть вопросы или если ваше мнение отличается от моего, пожалуйста, пишите комментарии ниже.

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









2024 © radiocodes.ru.