Android MVP (шаблон репозитория) получить изображение камеры/галереи?

Я пытаюсь реализовать архитектуру MVP, используя пример кода Google для mvp . У меня есть активность как View, у которой есть ведущий и модель. По нажатию кнопки пользователь может захватить и сохранить изображение во внешнем хранилище. И при захвате щелчка мне также нужно воспроизвести звук.

Я не уверен, какой код следует поместить в какой класс, потому что я не могу поместить код захвата камеры и воспроизведения звука в Activity (которое я рассматриваю как представление), чтобы представление было как можно более глупым, и я не могу поместить этот код в Presenter, потому что он использует Классы фреймворка Android (контекст и т. д.).

Таким образом, единственный вариант - поместить его в модель, но в примере кода модель имеет только репозитории (которые, как я полагаю, относятся только к локальным/удаленным источникам данных).

Как поместить этот код в модель и как связать его с другими компонентами, такими как View и Presenter? Какие-нибудь рекомендации?


person Nouman Bhatti    schedule 11.12.2017    source источник


Ответы (1)


Вот один из способов решения такой проблемы.

Ваша проблема в том, что какой-то код имеет смысл помещать в презентер, однако он слишком Androidy, поэтому вы можете просто interface его обойти.

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

interface CapturingSoundPlayer {
    void playSound();
}

interface ImageCapturer {
    void captureImage();
}

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

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

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

class Presenter {
    private final CapturingSoundPlayer soundPlayer;
    private final ImageCapturer capturer;

    Presenter(CapturingSoundPlayer soundPlayer, ImageCapturer capturer) {
        this.soundPlayer = soundPlayer;
        this.capturer = capturer;
    }

    void onCaptureButtonClicked() {
        soundPlayer.playSound();
        capturer.captureImage();
    }
}

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

Эти интерфейсы (и их реализация) являются просто логическими единицами/сущностями, которые ваш докладчик использует для разделения логики. Я просто думаю о функциях «захват» и «воспроизведение звука» как о простых действиях, как view.showLoading, и ваш докладчик играет оркестратор, он использует «что-то» для управления представлением, которое является интерфейсом представления, и использует что-то еще управлять звуком, который является интерфейсом для этого.

если репозитории считаются источниками данных, то, на мой взгляд, эти помощники не подходят под это определение.

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

Вы можете структурировать/организовать их по своему усмотрению, но только потому, что вы используете MVP, не каждый создаваемый вами класс должен быть одной из этих букв (M/V/P).

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

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

person elmorabea    schedule 11.12.2017
comment
Спасибо за ответ. Но я все еще запутался в части модели/репозитория, может быть, я слишком новичок. Не могли бы вы уточнить, где я должен реализовать эти интерфейсы, такие как фактический код для захвата и медиаплеера. Должен ли этот код быть в модели? Если да, то это не модель только для репозиториев, таких как источники данных (http/db). Должен ли я сделать CameraRepository и реализовать там эти интерфейсы? - person Nouman Bhatti; 11.12.2017
comment
Я обновил ответ, потому что он был слишком большим для комментария: D - person elmorabea; 11.12.2017
comment
поэтому я могу создать вспомогательный класс для захвата и воспроизведения звука. Это означает, что презентатор не обязан взаимодействовать только с моделью, чтобы делать что-то, он также может взаимодействовать с другими вспомогательными классами. Я думаю, что я слишком ограничен mvp. Японял твою точку зрения. С Уважением - person Nouman Bhatti; 11.12.2017
comment
Вы точно можете! и вы обнаружите, что модульное тестирование ваших помощников в изоляции будет проще, а также создаст хорошие небольшие классы докладчика/представления. - person elmorabea; 11.12.2017