Men Android dasturchisi sifatida sayohatimni boshlaganimda, "Mobil ilovalar arxitekturasi" so'zlari meni chuqur hayratda qoldirdi, Google va Habré haqidagi maqolalar meni yanada qattiq tushkunlikka soldi - men kitobga qarayman va hech narsani ko'rmayapman. O'ylaymanki, agar siz ushbu maqolani o'qiyotgan bo'lsangiz, siz ushbu rasmni bir necha marta o'rganib chiqdingiz va nima sodir bo'layotganini tushunishga harakat qildingiz: Mobil rivojlanishda me'moriy yondashuvni tushunish muammosi, menimcha, arxitekturaning mavhumligida yotadi. Har bir ishlab chiquvchining u yoki bu naqshni qanday qilib to'g'ri amalga oshirish haqida o'z qarashlari bor. MVPni amalga oshirishning ko'proq yoki kamroq munosib misollari Internetning ingliz tilida so'zlashuvchi sektorida topilgan, bu ajablanarli emas. Keling, nima ekanligini qisqacha ko'rib chiqamiz va misolga o'tamiz. Model - ma'lumotlar darajasi. Men "biznes mantig'i" atamasini ishlatishni yoqtirmayman, shuning uchun o'z ilovalarimda uni Repository deb atayman va u ma'lumotlar bazasi va tarmoq bilan aloqa qiladi. Ko‘rish — displey darajasi. Agar siz daf bilan raqsga tushishni va hayot tsikli bilan o'zaro munosabatda bo'lishni yoqtirmasangiz, bu Faoliyat , Fragment yoki Maxsus ko'rinish bo'ladi . Eslatib o'taman, dastlab barcha Android ilovalari MVC tuzilishiga bo'ysunadi , bu erda Controller Faoliyat yoki Fragment hisoblanadi . Taqdimotchi - View va Model o'rtasidagi qatlam. View o'zida sodir bo'lgan voqealarni uzatadi, taqdimotchi ularni qayta ishlaydi, agar kerak bo'lsa, Modelga kiradi va ma'lumotlarni ko'rsatish uchun Ko'rinishga qaytaradi. Android va aniq bir misol bilan bog'liq holda, men muhim qismni - Shartnomani ta'kidlayman. Bu yuqoridagi komponentlar orasidagi barcha o'zaro aloqalarni tavsiflovchi interfeys. Nazariy qismni umumlashtirish uchun:
- View Presenter haqida biladi;
- Taqdimotchi View va Model (Repository) haqida biladi;
- O'z-o'zidan model;
- Shartnoma ular o'rtasidagi o'zaro munosabatlarni tartibga soladi.
MainContract
:
public interface MainContract {
interface View {
void showText();
}
interface Presenter {
void onButtonWasClicked();
void onDestroy();
}
interface Repository {
String loadMessage();
}
}
Hozircha biz kelajakdagi ilovamizning 3 komponentini va ular nima qilishini ta'kidlaymiz. Keyin biz omborni tasvirlaymiz:
public class MainRepository implements MainContract.Repository {
private static final String TAG = "MainRepository";
@Override
public String loadMessage() {
Log.d(TAG, "loadMessage()");
/** Здесь обращаемся к БД or сети.
* Я специально ничего не пишу, чтобы не загромождать пример
* DBHelper'ами и прочими не относяшимеся к теме an objectми.
* Поэтому я буду возвращать строку Сосисочная =)
*/
return "Сосисочная у Лёхи»;
}
}
U bilan hamma narsa aniq, faqat ma'lumotlarni yuklash va tushirish. Keyingisi Taqdimotchi:
public class MainPresenter implements MainContract.Presenter {
private static final String TAG = "MainPresenter";
//Компоненты MVP applications
private MainContract.View mView;
private MainContract.Repository mRepository;
//Сообщение
private String message;
//Обрати внимание на аргументы конструктора - мы передаем экземпляр View, а Repository просто создаём конструктором.
public MainPresenter(MainContract.View mView) {
this.mView = mView;
this.mRepository = new MainRepository();
Log.d(TAG, "Constructor");
}
//View сообщает, что кнопка была нажата
@Override
public void onButtonWasClicked() {
message = mRepository.loadMessage();
mView.showText(message);
Log.d(TAG, "onButtonWasClicked()");
}
@Override
public void onDestroy() {
/**
* Если бы мы работали например с RxJava, в этом классе стоило бы отписываться от подписок
* Кроме того, при работе с другими методами асинхронного андроида,здесь мы боремся с утечкой контекста
*/
Log.d(TAG, "onDestroy()");
}
}
Men daf bilan raqsga tushish va hayot aylanishi haqida yozganimni eslaysizmi? Taqdimotchi o'z View umri davomida yashaydi, murakkab foydalanuvchi stsenariylarini ishlab chiqayotganda, men sizga Presenterdagi barcha View qayta qo'ng'iroqlarini takrorlashni maslahat beraman va ularni o'z vaqtida tushunish uchun Faoliyat/Fragmentning hayot aylanishini takrorlab, tegishli daqiqalarda qo'ng'iroq qiling. hozirda "interlayer" da osilgan ma'lumotlar bilan bajarilishi kerak. Va nihoyat, Ko'rish:
public class MainActivity extends AppCompatActivity implements MainContract.View {
private static final String TAG = "MainActivity";
private MainContract.Presenter mPresenter;
private Button mButton;
private TextView myTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Создаём Presenter и в аргументе передаём ему this - эта Activity расширяет интерфейс MainContract.View
mPresenter = new MainPresenter(this);
myTv = (TextView) findViewById(R.id.text_view);
mButton = (Button) findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPresenter.onButtonWasClicked();
}
});
Log.d(TAG, "onCreate()");
}
@Override
public void showText(String message) {
myTv.setText(message);
Log.d(TAG, "showMessage()");
}
//Вызываем у Presenter метод onDestroy, чтобы избежать утечек контекста и прочих неприятностей.
@Override
public void onDestroy() {
super.onDestroy();
mPresenter.onDestroy();
Log.d(TAG, "onDestroy()");
}
}
Nima gaplar?
- Faoliyat, shuningdek, View sifatida ham tanilgan,
onCreate()
usulda Presenter misolini yaratadi va o'zini uning konstruktoriga o'tkazadi. - Taqdimotchi yaratilganda, u aniq ko'rinishni oladi va Repository misolini yaratadi (aytmoqchi, uni Singleton qilish mumkin)
- Tugma bosilganda, View taqdimotchini taqillatadi va "tugma bosildi" deb aytadi.
- Taqdimotchi omborga murojaat qiladi: "Men uchun bu axlatni yuklab oling."
- Repozitariy "narsalarni" yuklaydi va Taqdimotchiga etkazib beradi.
- Taqdimotchi Ko'rishga o'girilib: "Mana siz uchun ma'lumotlar, uni chizing"
GO TO FULL VERSION