Подтвердить что ты не робот

MVP Android - Сколько докладчиков?

У меня есть быстрый вопрос. Я пытаюсь (и борюсь) разрабатывать свое приложение с шаблоном проектирования MVP.

Могу ли я спросить, должен ли я иметь отдельный класс презентатора для каждого представления (активности, фрагмента)?

Не так много ресурсов, которые я могу видеть в Интернете, что ясно показывает образцы MVP. Может ли кто-нибудь поделиться, если у них есть?

PS Я также использую RecyclerViewAdapter в этом приложении, поэтому любые указатели на это будут оценены

Заранее спасибо

4b9b3361

Ответ 1

Дизайн Model-View-Controller появился очень рано в программном обеспечении и первоначально использовался для таких элементов, как элемент кнопки. Вы используете MVP (в основном то же, что и MVC), чтобы получить архитектуру, которая является модульной и, следовательно, ее легко поддерживать, разделяя представление из логики.

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

http://antonioleiva.com/mvp-android/ дает теоретический обзор MVP.

Ответ 2

Хотя старый, это очень интересный вопрос. Поскольку MVP/MVC/MVVM сейчас является своего рода "гудными словами" в сообществе Android, этот вопрос заслуживает более полного ответа (IMHO).

Короткий ответ:

Одиночный презентатор может использоваться с несколькими видами

Длинный ответ:

В общем, нет ни одного единого определения MVP/MVC - существует много подходов к реализации этих архитектурных шаблонов. Вы не указали определение "своего" MVP, поэтому я могу только догадываться, что вы имеете в виду.

Тем не менее, существуют некоторые "лучшие практики" в объектно-ориентированном программировании, которые должны (в идеале) учитывать любую реализацию любого архитектурного шаблона.

Что вы спрашиваете, можете ли вы повторно использовать реализацию одного презентатора с разными представлениями, не так ли? Давайте рассмотрим этот вопрос через призму принципов SOLID.

"L" означает "Принцип замещения Лискова" (LSP). Это один из самых непонятых принципов в SOLID, но общая идея этого принципа гласит следующее:

LSP: если фрагмент кода работает с объектом класса A, он также должен работать без проблем с объектами любого подкласса A (то есть подклассы должны можно использовать вместо А всюду)

Пример нарушения LSP в Android: Context: sublasses из Context (например, Application и Activity) не эквивалентны. Некоторый код, который требует Context, может работать без проблем с Application, но если вы передадите вместо него Activity, произойдет утечка памяти (это очень распространенная ошибка в приложениях Android, которая вызвана прежде всего нарушением LSP разработчиками Google).

Верните свой вопрос. Я предполагаю, что ваш презентатор выглядит так (обратите внимание на интерфейс для просмотров):

public class SomePresenter {

    /**
     * Views bound to this presenter must implement this interface
     */
    interface SomeView {
        void doSomething1();
        void doSomething2();
    }

    public void bindView(SomeView someView) {
        // view binding logic
    }

    // more presenter methods

}

LSP утверждает, что любой класс, реализующий SomeView, можно использовать с SomePresenter. Ведущий не должен заботиться о том, передается ли ему реализация SomeView Activity, Fragment или, может быть, просто макет для unit test.

Итак, полный ответ на ваш вопрос: один ведущий может быть повторно использован с разными представлениями, если ведущий не зависит от конкретных реализаций представлений, а только от их суперкласса.

Дополнительная информация:

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

Мое личное мнение заключается в том, что в MVC/MVP ни Activity, ни Fragment не должны быть представлениями. Обоснование этой претензии приведено в этом сообщении: Почему действия в Android не являются элементами пользовательского интерфейса.

введите описание изображения здесь

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

Ответ 3

В вашей деятельности/фрагменте должно быть 1 ведущий.  Мне нравится делать все мои действия для расширения из BaseActivity, а затем я делаю, чтобы эта BaseActivity требовала Presenter, см. Этот пример:

    public abstract class BaseActivity<Presenter extends BasePresenter> extends AppCompatActivity {

    protected Presenter mPresenter;

    @NonNull
    protected abstract Presenter createPresenter(@NonNull final Context context);

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = createPresenter(this);
        mPresenter.onCreate(savedInstanceState);
        }
    }
    // other lifecycle methods

А затем создайте абстрактный BasePresenter

public abstract class BasePresenter {

protected BasePresenter() {
}

@NonNull
public static BasePresenter nullPresenter(@NonNull final Context context) {
    return new BasePresenter() {};
}

@CallSuper
public void onCreate(@Nullable final Bundle savedInstanceState) {
}

Теперь, создавая действие, сделайте следующее:

public class MyActivity extends BaseActivity<MyActivityPresenter>{


@Override
MyActivityPresenter createPresenter(@NoNull final Context context){
     return new MyActivityPresenter(all, Your, Dependencies, Here);
    }
}

Теперь смотрите это видео и понимайте ответственность Activity/View в MVP.