Menyembunyikan / menonaktifkan fitur untuk beberapa pengguna

10

Katakanlah saya memiliki versi aplikasi yang gratis dan berbayar. Versi berbayar adalah superset versi gratis mengenai fitur yang tersedia bagi pengguna, artinya versi berbayar akan memiliki semua fitur aplikasi gratis plus tambahan.

Apakah ada pola untuk beralih ketersediaan fitur berdasarkan pada flag yang dimuat saat startup (mis. Gratis / berbayar)?

Saya tidak suka gagasan memiliki blok kode berikut di mana-mana:

if(isFreeVersion){
    // ...
} else {
    // ...
}

Memiliki 2 cabang git yang terpisah untuk setiap versi bukanlah suatu pilihan karena itu berarti mempertahankan 2 (atau lebih) sumber kode, tampaknya tidak praktis secara umum dan dibahas lebih lanjut di sini: Mempertahankan Dua Versi Perangkat Lunak yang Terpisah Dari Codebase yang Sama dalam Kontrol Versi .

Apakah ada cara untuk melakukan ini, sementara masih memiliki basis kode tunggal dan tidak membuang sampah sembarangan kode dengan pernyataan bersyarat yang memeriksa bendera gratis / berbayar?

Saya yakin ini telah dibahas berkali-kali sebelumnya dan saya yakin ada beberapa pola untuk mendekati masalah ini, tetapi saya tidak dapat menemukannya.

Kami menggunakan Android / Java.

Tadija Bagarić
sumber
@gnat tnx, temukan bagus. Tapi saya ingin membahas opsi yang tidak memerlukan cabang terpisah dan mempertahankan beberapa basis kode
Tadija Bagarić
2
Ini terlihat mirip dengan memiliki tingkat otorisasi yang berbeda. Anda mungkin melihat bagaimana masalah itu biasanya ditangani, di mana fitur hanya tersedia untuk pengguna / peran tertentu.
Bart van Ingen Schenau
@ BartvanIngenSchenau Saya merasa sebagian besar berupa ifpemeriksaan untuk menyembunyikan kontrol untuk fitur terlarang atau melakukan dialog sembulan ketika pengguna mencoba melakukan apa yang tidak diizinkan. Saya berharap menemukan cara untuk menghindari banyak persyaratan dalam kode
Tadija Bagarić
2
Gunakan poliformisme. Anda tidak akan pernah bertanya pada diri sendiri tentang pernyataan jika ini lagi, dan itu akan BANYAK lebih mudah untuk dipertahankan!
Steve Chamaillard

Jawaban:

14

Suka bersyarat if(isFreeVersion)harus muncul hanya sekali dalam kode. Ini bukan pola, tapi saya yakin Anda sudah tahu nama untuk itu: itu disebut prinsip KERING . Memiliki kode seperti " if(isFreeVersion)" di lebih dari satu tempat dalam kode Anda berarti Anda mengulangi baris ini / logika di dalamnya, yang berarti kode itu harus di refactored untuk menghindari pengulangan.

" if(isFreeVersion)" harus digunakan untuk mengatur daftar opsi konfigurasi internal untuk berbagai fitur. Kode yang dihasilkan kemudian dapat terlihat seperti ini:

 if(isFreeVersion)
 {
      feature1Enabled=false;
      feature2Enabled=false;
      maxNoOfItems=5;
      advertisingStrategy=new ShowLotsOfAdvertisementsStrategy();
      // ...
 } 
 else
 {
      feature1Enabled=true;
      feature2Enabled=true;
      maxNoOfItems=int.MaxValue; // virtually unlimited
      advertisingStrategy=new ShowMinimalAdvertisementsStrategy();
 }

Ini memetakan satu bendera "isFreeVersion" Anda ke fitur yang berbeda . Catatan Anda dapat memutuskan di sini jika Anda lebih suka menggunakan flag boolean individu untuk fitur individual, atau menggunakan beberapa jenis parameter lain, misalnya objek strategi yang berbeda dengan antarmuka umum, jika kontrol fitur memerlukan parametrization yang lebih kompleks.

Sekarang Anda memiliki kendali atas apa yang ada di versi gratis dan apa yang ada di versi berbayar di satu tempat, yang membuat pemeliharaan logika ini cukup sederhana. Anda masih harus berhati-hati karena kode Anda tidak penuh dengan banyak if(feature1Enabled)pernyataan (dengan mengikuti prinsip KERING), tetapi sekarang pemeliharaan pemeriksaan ini tidak lagi menyakitkan. Misalnya, Anda memiliki kontrol yang lebih baik terhadap apa yang perlu Anda ubah ketika Anda ingin menjadikan fitur berbayar yang ada gratis (atau sebaliknya).

Akhirnya marilah kita lihat ke dalam artikel blog Fowler tentang matikan fitur , di mana ia berbicara tentang titik masuk fitur / beralih poin. Izinkan saya mengutip satu poin utama:

Jangan mencoba untuk melindungi setiap jalur kode dalam kode fitur baru dengan toggle, fokus hanya pada titik masuk yang akan mengarahkan pengguna ke sana dan beralih titik entri tersebut.

Jadi sebagai strategi keseluruhan, fokuslah pada antarmuka pengguna dan batasi cek Anda pada jumlah minimal poin yang diperlukan untuk membuat fitur tertentu muncul atau menghilang. Itu harus menjaga basis kode Anda tetap bersih, tanpa kekacauan yang tidak perlu.

Doc Brown
sumber
5
Anda pada dasarnya telah mengganti IsFreeVersion dengan FeaturexEnabled, Anda belum mengurangi jumlah panggilan. Meskipun saya belum memiliki kasus yang persis seperti itu, saya selalu menangani hal-hal serupa pada saat pembuatan menu menonaktifkan opsi-opsi yang seharusnya tidak dilihat pengguna. Sebagian besar ini pada pembuatan formulir tetapi kadang-kadang saya harus melakukannya ketika menyiapkan menu pop-up.
Loren Pechtel
1
@ LorenPechtel: Anda harus membaca jawaban saya lagi, lebih hati-hati. Sebenarnya saya menyebutkan dua hal untuk mengurangi jumlah tes bersyarat, salah satunya prinsip KERING, salah satunya fokus pada tes di UI. Lebih penting, pemetaan bendera tidak spesifik seperti isFreeVersionuntuk spesifik Menghapus parameter fitur yang paling dari rasa sakit dari tes mereka - mereka akan benar-benar mulai masuk akal dan tidak menghasilkan kekacauan pemeliharaan lagi.
Doc Brown
9

Jika Anda tidak suka if/elseblok, maka Anda bisa refactor mereka untuk menggunakan warisan (lihat Ganti kondisional dengan polimorfisme dari buku Refactoring Marin Fowler ). Ini akan:

  • Buat sedikit lebih mudah untuk alasan tentang kode Anda.

  • Memungkinkan untuk memiliki dua kelas, satu untuk versi gratis dan yang lainnya untuk versi berbayar, yang pada gilirannya akan mengirim panggilan ke kelas lain, memastikan bahwa perbedaan antara versi gratis dan berbayar terbatas pada dua kelas (tiga menghitung kelas dasar).

  • Mudahkan, nanti, untuk menambahkan bentuk lain dari perangkat lunak Anda, seperti varian murah atau versi premium. Anda hanya akan menambahkan kelas lain, dan mendeklarasikannya sekali dalam kode Anda, dan Anda akan tahu seluruh basis kode akan tetap berfungsi seperti yang diharapkan.

Arseni Mourzenko
sumber
3
Saya pikir Anda mungkin ingin menjadi lebih jelas bahwa warisan implementasi tidak diperlukan untuk ini. Manfaat lain adalah aplikasi gratis dapat dikirimkan tanpa fitur premium. Memodifikasi kode byte Java untuk membuat kondisi jika selalu benar tidak terlalu sulit.
JimmyJames
6

Menurut saya pertanyaan Anda dapat diselesaikan dengan cukup baik dengan menerapkan Pola Toggle Fitur .

Seperti yang sering terjadi, Pete Hodgson menjelaskan dalam satu artikel semua skenario yang Anda bisa hadapi menerapkan pola ini, jauh lebih baik yang bisa saya lakukan.

Ada juga beberapa perpustakaan yang mendukung pola ini. Saya punya pengalaman bekerja dengan FF4J di Jawa tapi saya kira jika Anda mengetik:

feature toggle <whatever language you prefer>

... di mesin pencari mana pun Anda akan mendapatkan beberapa solusi.

danidemi
sumber
1

Ada lebih dari satu cara untuk mencapai ini. Cara sederhana dan lurus ke depan adalah dengan menggunakan Pola Fitur Toggle yang disediakan dalam begitu banyak artikel. Pendekatan selanjutnya harus dilakukan dengan merancang untuk fitur yang dapat dipasang. Baik Android dan iOS memiliki pembayaran dalam aplikasi. Bersamaan dengan itu, pembayaran berpotensi untuk mengunduh.

Saat Anda melihat Servlets, JAMES Mailets, dan bahkan plugin IDE, mereka semua menggunakan konsep arsitektur plug-in:

  • Tetapkan antarmuka yang aplikasi Anda tahu cara menggunakannya. Antarmuka itu perlu menyediakan cara untuk menyuntikkan dirinya ke dalam navigasi aplikasi Anda dan aplikasi apa pun lainnya ke titik sentuh plugin.
  • Siapkan jalur yang akan dibaca aplikasi Anda saat start up (manajemen plugin run-time jauh lebih sulit)
  • Jika ada plugin (seperti file Java Jar), ​​aplikasi akan membaca manifes untuk menemukan implementasi antarmuka plugin, atau memindai kelas yang mengimplementasikan antarmuka.
  • Setelah kelas itu ditemukan, ia dipakai dan metode yang sesuai dipanggil untuk mengintegrasikan fitur-fitur baru.

Apa ini juga memungkinkan Anda adalah kesempatan untuk memiliki berbagai kelas fitur yang tersedia untuk audiens yang berbeda. Pengguna hanya memiliki fitur yang mereka bayar.

Kode aplikasi Anda dipertahankan sebagai satu basis kode, dan plug-in Anda adalah basis kode yang terpisah - tetapi hanya mencakup bagian-bagian yang relevan dengan plugin. Aplikasi tahu cara menangani plugin saat ada, dan plugin hanya tahu cara berinteraksi dengan antarmuka.

Berin Loritsch
sumber