Kali ini kita akan membahas tentang apa itu arsitektur MVP atau biasa disebut design pattern. Sebenernya ada banyak design pattern seperti MVP, MVVM, MVC, DAO, Singleton dan lain-lain, lantas apakah perbedaan dari masing–masing design pattern tersebut? Jawabannya adalah tergantung pada penggunaan dan efektifitas mana yang lebih baik digunakan. Namun yang akan kami bahas hanya mengenai MVP karena design pattern ini yang sering umum digunakan pada pengembangan aplikasi android.

Apa itu MVP ?

Model-View-Presenter atau yang biasa disingkat menjadi MVP adalah sebuah konsep arsitektur pengembangan aplikasi yang memisahkan antara tampilan aplikasi dengan proses bisnis yang bekerja pada aplikasi. Arsitektur ini akan membuat pengembangan aplikasi kita menjadi lebih terstuktur, mudah di-test dan juga mudah di-maintain.

Berikut penjelasan masing-masing layer pada MVP.

  • View, merupakan layer untuk menampilkan data dan interaksi ke user. View biasanya berupa Activity, Fragment atau Dialog di Android. View ini juga yang langsung berkomunikasi dengan user.
  • Model, merupakan layer yang menunjuk kepada objek dan data yang ada pada aplikasi.
  • Presenter, merupakan layer yang menghubungkan komunikasi antara Model dan View. Setiap interaksi yang dilakukan oleh user akan memanggil Presenter untuk memrosesnya dan mengakses Model lalu mengembalikan responnya kembali kepada View.

Manfaat menggunakan MVP Arsitektur:
-Membuat code menjadi rapi dan mudah dibaca
-Memudahkan dalam pekerjaan team
-Memudahkan dalam perubahan code / refactoring
-Memudahakan dalam mencari dan menganalisa bug
-Mudah untuk ditesting

Komponen MVP

Komponen dari MVP, benarlah sebuah Model, View dan Presenter. Namun lebih detailnya pada sebuah Activity ada beberapa komponen class yang harus dibuat supaya kita bisa menerapkan paradigma MVP pada codingan kita.
Misalnya kalian mempunyai sebuah class, MainActivity, maka komponen2 Presenter yang harus dibuat adalah sebagai berikut :

  • MainPresenter : sebuah interface yang berisi nama fungsi-fungsi logika dari class MainActivity. Menghubungkan View dengan Presenter.
  • MainPresenterImp : sebuah class yang mengimplementasikan fungsi2 yang ada pada mainPresenter
  • MainView : Sebuah interface yang berisi fungsi2 yang akan dijalankan pada MainActivity, menghubungkan Presenter ke View.

Bagaimana implementasinya?
Berikut akan saja buat projek sederhana untuk contoh implementasinya beserta langkah-langkanya.

Struktur project yang kita buat nantinya akan seperti ini.

Sebelumnya masukkan terlebih dahulu library yang dibutuhkan.

dependencies {
    implementation 'com.android.support:recyclerview-v7:27.1.1'    
}

Pertama, kita buat project baru dengan nama androidmvpsample
Lalu kita Activity dengan nama MainActivity

Lalu pada activity_main.xml modifikasi seperti berikut

<?xml version='1.0' encoding='utf-8'?>
<RelativeLayout xmlns:android='http://schemas.android.com/apk/res/android'
    xmlns:app='http://schemas.android.com/apk/res-auto'
    xmlns:tools='http://schemas.android.com/tools'
    android:layout_width='match_parent'
    android:layout_height='match_parent'
    android:orientation='vertical'
    tools:context='.MainActivity'>

    <android.support.v7.widget.RecyclerView
        android:id='@+id/recycler_view'
        android:layout_width='match_parent'
        android:layout_height='match_parent'></android.support.v7.widget.RecyclerView>

    <Button
        android:id='@+id/button_add'
        android:layout_width='wrap_content'
        android:layout_height='wrap_content'
        android:layout_alignParentBottom='true'
        android:layout_centerHorizontal='true'
        android:layout_marginBottom='16dp'
        android:background='@color/colorPrimary'
        android:textColor='@android:color/white'
        android:text='Tambah'/>
</RelativeLayout>

Lalu, kita buat data model-nya dengan nama User.java

public class User {

    private int id;
    private String nama;
    private String status;
    private String pekerjaan;
    private String noHp;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNama() {
        return nama;
    }

    public void setNama(String nama) {
        this.nama = nama;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getPekerjaan() {
        return pekerjaan;
    }

    public void setPekerjaan(String pekerjaan) {
        this.pekerjaan = pekerjaan;
    }

    public String getNoHp() {
        return noHp;
    }

    public void setNoHp(String noHp) {
        this.noHp = noHp;
    }
}

Lalu , kita buat interface untuk view dengan nama MainView.java

public interface MainView {

    void onLoad(List<User> users);

    void onSave();

    void onDelete();

    void onUpdate();
}

lalu, kita buat interface untuk presenter dengan nama MainPresenter.java

public interface MainPresenter {

    void save(User user);

    void update(User user);

    void delete(User user);

    void load();
}

Lalu, kita buat class untuk implementasi dari MainPresenter.java dengan nama MainPresenterImpl.java

public class MainPresenterImpl implements MainPresenter {

    private MainView mainView; 

    public MainPresenterImpl(MainView mainView) {
        this.mainView = mainView;
    }

    @Override
    public void save(User user) {

    }

    @Override
    public void update(User user) {

    }

    @Override
    public void delete(User user) {

    }

    @Override
    public void load() {

    }
}

setelah itu kita modifikasi MainPresenterImpl.java seperti berikut

public class MainPresenterImpl implements MainPresenter {

    private MainView mainView;
    private List<User> users = new ArrayList<>();
    private int no = 4;

    public MainPresenterImpl(MainView mainView) {
        this.mainView = mainView;
        init();
    }

    private void init() {
        User user = new User();
        user.setId(1);
        user.setNama('Kristiawan Adi');
        user.setNoHp('085330684114');
        user.setPekerjaan('Java Programmer');
        user.setStatus('Jomblo sejak lahir');
        users.add(user);

        User user1 = new User();
        user1.setId(2);
        user1.setNama('Bimo Joko');
        user1.setNoHp('085474748888');
        user1.setPekerjaan('IT Scurity');
        user1.setStatus('Udah punya pacar tapi drama melulu');
        users.add(user1);

        User user2 = new User();
        user2.setId(3);
        user2.setNama('Dirga');
        user2.setNoHp('085332423043');
        user2.setPekerjaan('IT Security');
        user2.setStatus('Udah punya pacar dan bentar lagi nikah');
        users.add(user2);
    }

    @Override
    public void save(User user) {
        no++;
        user.setId(no);
        users.add(user);

        mainView.onSave();
    }

    @Override
    public void update(User user) {
        for (User model : users){
            if (model.getId() == user.getId()){
                model.setNama(user.getNama());
                model.setStatus(user.getStatus());
                model.setPekerjaan(user.getPekerjaan());
                model.setNoHp(user.getNoHp());

                break;
            }
        }

        mainView.onUpdate();
    }

    @Override
    public void delete(User user) {
        users.remove(user);

        mainView.onDelete();
    }

    @Override
    public void load() {
        mainView.onLoad(users);
    }
}

Lalu kita buat layout dengan nama item_view_user.xml

 

<?xml version='1.0' encoding='utf-8'?>
<LinearLayout xmlns:android='http://schemas.android.com/apk/res/android'
    android:orientation='vertical' android:layout_width='match_parent'
    android:layout_height='wrap_content'
    android:padding='16dp'>

    <TextView
        android:id='@+id/nama'
        android:layout_width='match_parent'
        android:layout_height='wrap_content'
        android:textSize='16dp'
        android:textColor='@android:color/black'
        android:textStyle='bold'
        android:text='Nama'/>
    <TextView
        android:id='@+id/status'
        android:layout_width='match_parent'
        android:layout_height='wrap_content'
        android:text='Status'/>

</LinearLayout>

Selanjutnya, kita buat class adapter untuk menampilkan list menggunakan recycler view dengan nama MainRecyclerAdapter.java

 

public class MainRecyclerAdapter extends RecyclerView.Adapter<MainRecyclerAdapter.ViewHolder> {

    private List<User> users;
    private OnCallbackListener listener;

    public MainRecyclerAdapter(List<User> users) {
        this.users = users;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_user, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        User user = users.get(position);
        holder.textViewNama.setText(user.getNama());
        holder.textViewStatus.setText(user.getStatus());
    }

    @Override
    public int getItemCount() {
        return users.size();
    }

    public void setOnCallbackListener(OnCallbackListener listener) {
        this.listener = listener;
    }

    class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView textViewNama;
        TextView textViewStatus;

        public ViewHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);

            textViewNama = itemView.findViewById(R.id.nama);
            textViewStatus = itemView.findViewById(R.id.status);
        }

        @Override
        public void onClick(View v) {
            if (listener != null) {
                listener.onClick(users.get(getAdapterPosition()));
            }
        }
    }

    public interface OnCallbackListener {

        void onClick(User user);
    }
}

lalu pada class MainActivity.java kita buat sebagai berikut kita implementasikan interface MainView pada MainActivity

 

public class MainActivity extends AppCompatActivity implements MainView {

    private RecyclerView recyclerView;
    private Button buttonAdd;
    private MainRecyclerAdapter adapter;
    private List<User> userList = new ArrayList<>();
    private AppCompatDialog dialog;
    private MainPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        presenter = new MainPresenterImpl(this);

        recyclerView = findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        adapter = new MainRecyclerAdapter(userList);
        recyclerView.setAdapter(adapter);

        buttonAdd = findViewById(R.id.button_add);

    }

    @Override
    public void onLoad(List<User> users) {

    }

    @Override
    public void onSave() {

    }

    @Override
    public void onDelete() {

    }

    @Override
    public void onUpdate() {

    }

}

lalu kita buat layout dialog_input.xml seperti berikut

<?xml version='1.0' encoding='utf-8'?>
<LinearLayout xmlns:android='http://schemas.android.com/apk/res/android'
    android:layout_width='match_parent'
    android:layout_height='wrap_content'
    android:orientation='vertical'
    android:padding='10dp'>

    <EditText
        android:id='@+id/edittext_nama'
        android:layout_width='match_parent'
        android:layout_height='wrap_content'
        android:hint='Nama' />

    <EditText
        android:id='@+id/edittext_nohp'
        android:layout_width='match_parent'
        android:layout_height='wrap_content'
        android:hint='Nomor HP' />

    <EditText
        android:id='@+id/edittext_pekerjaan'
        android:layout_width='match_parent'
        android:layout_height='wrap_content'
        android:hint='Pekerjaan' />

    <EditText
        android:id='@+id/edittext_status'
        android:layout_width='match_parent'
        android:layout_height='wrap_content'
        android:hint='Status' />

    <RelativeLayout
        android:layout_width='match_parent'
        android:layout_height='wrap_content'
        android:layout_marginBottom='5dp'
        android:layout_marginTop='40dp'>

        <Button
            android:id='@+id/button_save'
            android:layout_width='wrap_content'
            android:layout_height='wrap_content'
            android:layout_alignParentTop='true'
            android:layout_marginRight='16dp'
            android:layout_toStartOf='@+id/button_cancel'
            android:text='Simpan'
            android:textAllCaps='false' />

        <Button
            android:id='@+id/button_cancel'
            android:layout_width='wrap_content'
            android:layout_height='wrap_content'
            android:layout_alignParentEnd='true'
            android:layout_alignParentTop='true'
            android:text='Cancel'
            android:textAllCaps='false' />
    </RelativeLayout>

</LinearLayout>

Berikutnya kita modifikasi MainActivity dengan menambahkan dialog untuk input data, edit dan delete

Tambahkan 2 method dibawah ini:

public void showDialogInput() {
    dialog = new AppCompatDialog(this);
    dialog.setContentView(R.layout.dialog_input);
    dialog.setTitle('');

    final EditText editTextNama = dialog.findViewById(R.id.edittext_nama);
    final EditText editTextNoHp = dialog.findViewById(R.id.edittext_nohp);
    final EditText editTextPekerjaan = dialog.findViewById(R.id.edittext_pekerjaan);
    final EditText editTextStatus = dialog.findViewById(R.id.edittext_status);

    Button buttonSave = dialog.findViewById(R.id.button_save);
    buttonSave.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            User user = new User();
            user.setNama(editTextNama.getText().toString());
            user.setNoHp(editTextNoHp.getText().toString());
            user.setPekerjaan(editTextPekerjaan.getText().toString());
            user.setStatus(editTextStatus.getText().toString());

            presenter.save(user);
            dialog.dismiss();
        }
    });

    Button buttonCancel = dialog.findViewById(R.id.button_cancel);
    buttonCancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dialog.dismiss();
        }
    });

    if (!dialog.isShowing()) {
        dialog.show();
    }
}

public void showDialogDetail(final User user) {
    dialog = new AppCompatDialog(this);
    dialog.setContentView(R.layout.dialog_input);
    dialog.setTitle('');

    final EditText editTextNama = dialog.findViewById(R.id.edittext_nama);
    final EditText editTextNoHp = dialog.findViewById(R.id.edittext_nohp);
    final EditText editTextPekerjaan = dialog.findViewById(R.id.edittext_pekerjaan);
    final EditText editTextStatus = dialog.findViewById(R.id.edittext_status);

    editTextNama.setText(user.getNama());
    editTextNoHp.setText(user.getNoHp());
    editTextPekerjaan.setText(user.getPekerjaan());
    editTextStatus.setText(user.getStatus());

    Button buttonUpdate = dialog.findViewById(R.id.button_save);
    buttonUpdate.setText('Update');
    buttonUpdate.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            user.setNama(editTextNama.getText().toString());
            user.setNoHp(editTextNoHp.getText().toString());
            user.setPekerjaan(editTextPekerjaan.getText().toString());
            user.setStatus(editTextStatus.getText().toString());

            presenter.update(user);
            dialog.dismiss();
        }
    });

    Button buttonDelete = dialog.findViewById(R.id.button_cancel);
    buttonDelete.setText('Delete');
    buttonDelete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            presenter.delete(user);
            dialog.dismiss();
        }
    });

    if (!dialog.isShowing()) {
        dialog.show();
    }
}

Lalu kita buat dan gunakan fungsi-fungsi presenter dan fungsi lainya hingga seperti berikut

public class MainActivity extends AppCompatActivity implements MainView {

    private RecyclerView recyclerView;
    private Button buttonAdd;
    private MainRecyclerAdapter adapter;
    private List<User> userList = new ArrayList<>();
    private AppCompatDialog dialog;
    private MainPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        presenter = new MainPresenterImpl(this);

        recyclerView = findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        adapter = new MainRecyclerAdapter(userList);
        adapter.setOnCallbackListener(new MainRecyclerAdapter.OnCallbackListener() {
            @Override
            public void onClick(User user) {
                showDialogDetail(user);
            }
        });

        recyclerView.setAdapter(adapter);

        buttonAdd = findViewById(R.id.button_add);
        buttonAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialogInput();
            }
        });

        presenter.load();
    }

    @Override
    public void onLoad(List<User> users) {
        userList.clear();
        userList.addAll(users);
        adapter.notifyDataSetChanged();
    }

    @Override
    public void onSave() {
        Toast.makeText(this, 'Berhasil disimpan!', Toast.LENGTH_SHORT).show();
        presenter.load();
    }

    @Override
    public void onDelete() {
        Toast.makeText(this, 'Berhasil dihapus!', Toast.LENGTH_SHORT).show();
        presenter.load();
    }

    @Override
    public void onUpdate() {
        Toast.makeText(this, 'Berhasil diperbarui!', Toast.LENGTH_SHORT).show();
        presenter.load();
    }

    public void showDialogInput() {
        dialog = new AppCompatDialog(this);
        dialog.setContentView(R.layout.dialog_input);
        dialog.setTitle('');

        final EditText editTextNama = dialog.findViewById(R.id.edittext_nama);
        final EditText editTextNoHp = dialog.findViewById(R.id.edittext_nohp);
        final EditText editTextPekerjaan = dialog.findViewById(R.id.edittext_pekerjaan);
        final EditText editTextStatus = dialog.findViewById(R.id.edittext_status);

        Button buttonSave = dialog.findViewById(R.id.button_save);
        buttonSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                User user = new User();
                user.setNama(editTextNama.getText().toString());
                user.setNoHp(editTextNoHp.getText().toString());
                user.setPekerjaan(editTextPekerjaan.getText().toString());
                user.setStatus(editTextStatus.getText().toString());

                presenter.save(user);
                dialog.dismiss();
            }
        });

        Button buttonCancel = dialog.findViewById(R.id.button_cancel);
        buttonCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        if (!dialog.isShowing()) {
            dialog.show();
        }
    }

    public void showDialogDetail(final User user) {
        dialog = new AppCompatDialog(this);
        dialog.setContentView(R.layout.dialog_input);
        dialog.setTitle('');

        final EditText editTextNama = dialog.findViewById(R.id.edittext_nama);
        final EditText editTextNoHp = dialog.findViewById(R.id.edittext_nohp);
        final EditText editTextPekerjaan = dialog.findViewById(R.id.edittext_pekerjaan);
        final EditText editTextStatus = dialog.findViewById(R.id.edittext_status);

        editTextNama.setText(user.getNama());
        editTextNoHp.setText(user.getNoHp());
        editTextPekerjaan.setText(user.getPekerjaan());
        editTextStatus.setText(user.getStatus());

        Button buttonUpdate = dialog.findViewById(R.id.button_save);
        buttonUpdate.setText('Update');
        buttonUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                user.setNama(editTextNama.getText().toString());
                user.setNoHp(editTextNoHp.getText().toString());
                user.setPekerjaan(editTextPekerjaan.getText().toString());
                user.setStatus(editTextStatus.getText().toString());

                presenter.update(user);
                dialog.dismiss();
            }
        });

        Button buttonDelete = dialog.findViewById(R.id.button_cancel);
        buttonDelete.setText('Delete');
        buttonDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                presenter.delete(user);
                dialog.dismiss();
            }
        });

        if (!dialog.isShowing()) {
            dialog.show();
        }
    }
}

Selesai, lalu coba jalankan hasilnya akan seperti berikut

Kalian juga padat melihat atau download projectnya pada link dibawah ini

https://github.com/lutvie72/android-mvp-sample

Untuk tutorial berikutnya, kita akan membahas penerapan MVP Design Pattern pada API menggunakan retrofit.

Share :

1 Komentar

Berikan Komentar

*Komentar yang memuat konten kurang pantas akan dihapus secara permanen



Apabila Anda ingin membuat artikel untuk kami sertakan dalam daftar artikel website kami, silakan submit artikel Anda disini

Rack Edan, Rack Spira