Bazı kullanıcılar için özellikleri gizleme / devre dışı bırakma


11

Diyelim ki uygulamanın ücretsiz ve ücretli bir sürümü var. Ücretli sürüm, kullanıcıların kullanabileceği özelliklerle ilgili ücretsiz sürümün bir üst kümesidir, yani ücretli sürüm, ücretsiz uygulamanın tüm özelliklerine ve ekstraya sahip olacaktır.

Başlangıçta yüklenen bir bayrağa (ör. Ücretsiz / ücretli) dayalı özellik kullanılabilirliğini değiştirmek için bir model var mı?

Aşağıdaki kod blokları her yerde olması fikri sevmiyorum:

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

Her sürüm için 2 ayrı git dalına sahip olmak bir seçenek değildir, çünkü 2 (veya daha fazla) kod kaynağını korumak anlamına gelir, genel olarak pratik görünmez ve burada daha fazla tartışılır: Sürüm Kontrolünde Aynı Kod Tabanından İki Ayrı Yazılım Sürümünün Korunması .

Bunu hala tek bir kod tabanına sahipken ve kodu ücretsiz / ücretli bayrağı kontrol eden koşullu ifadelerle doldurmamak için yapmanın bir yolu var mı?

Bunun daha önce birçok kez tartışıldığından eminim ve bu soruna yaklaşmak için bazı desenler olduğundan eminim, ancak bulamıyorum.

Android / Java kullanıyoruz.



@gnat tnx, güzel bul. Ancak ayrı dallara ihtiyaç duymayan ve birden fazla kod tabanına sahip olmayan seçenekleri tartışmak istiyorum
Tadija Bagarić

2
Bu, farklı yetki seviyelerine sahip olmaya benzer. Bir özelliğin yalnızca belirli kullanıcılar / roller için kullanılabildiği bu sorunun genellikle nasıl ele alınacağını inceleyebilirsiniz.
Bart van Ingen Schenau

@BartvanIngenSchenau Çoğunlukla ifyasak özellikler için denetimleri gizlemek veya kullanıcı izin vermediği şeyi yapmaya çalıştığında açılan iletişim kutusu açmak için kontroller olduğunu düşünüyorum.
Kodda

2
Çok yönlülük kullanın. Bu ifade hakkında kendinize bir daha sormak zorunda kalmayacaksınız ve bakımı çok daha kolay olacak!
Steve Chamaillard

Yanıtlar:


9

if/elseBlokları sevmiyorsanız , kalıtım kullanmak için onları yeniden düzenleyebilirsiniz (bkz . Marin Fowler'in Yeniden Düzenleme kitabındaki polimorfizm ile koşullu değiştirme ). Bu:

  • Kodunuz hakkında akıl yürütmeyi biraz daha basit hale getirin.

  • Biri ücretsiz sürüm ve diğeri ücretli sürüm için olmak üzere iki sınıfa olanak tanır, bu da çağrıları diğer sınıflara gönderir ve ücretsiz ve ücretli sürümler arasındaki ayrımın iki sınıfla sınırlandırılmasını sağlar (üçü sayma temel sınıf).

  • Daha sonra, ucuz bir varyant veya premium sürüm gibi yazılımınızın diğer formlarını eklemeyi kolaylaştırın. Başka bir sınıf ekleyecek ve kodunuzda bir kez beyan edeceksiniz ve tüm kod tabanının beklendiği gibi çalışacağını bileceksiniz.


3
Bunun için uygulamanın mirasının gerekli olmadığı konusunda daha açık olmak isteyebilirsiniz . Diğer bir avantaj, ücretsiz uygulamanın premium özellikler olmadan teslim edilebilmesidir. Bir if koşulunu her zaman doğru yapmak için Java bayt kodunu değiştirmek çok zor değildir.
JimmyJames

15

Koşullu bir kodda if(isFreeVersion)sadece bir kez olmalıdır . Bu bir desen değil, ama eminim zaten adını biliyorsunuz: buna KURU ilkesi denir . Kodunuzda if(isFreeVersion)birden fazla yerde " " gibi bir kod bulunması, bu satırı / içindeki mantığı tekrarladığınız anlamına gelir, bu da tekrardan kaçınmak için yeniden düzenlenmesi gerektiği anlamına gelir.

if(isFreeVersion)Farklı özellikler için dahili yapılandırma seçeneklerinin bir listesini ayarlamak için " " kullanılmalıdır. Sonuçta ortaya çıkan kod şöyle görünebilir:

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

Bu, tek "isFreeVersion" bayrağınızı farklı özelliklere eşler . Tek tek özellikler için ayrı boolean bayrakları kullanmayı veya özellik kontrolü daha karmaşık bir parametrelendirme gerektiriyorsa, ortak arabirime sahip farklı strateji nesneleri gibi başka bir tür parametre kullanmayı tercih ederseniz burada karar verebilirsiniz.

Şimdi, ücretsiz sürümde neyin ve ücretli sürümde neyin tek bir yerde kontrol edileceğini, bu da bu mantığın bakımını oldukça basit hale getirir. Yine de if(feature1Enabled)(DRY ilkesini izleyerek) kodunuzu çok sayıda ifadeyle karıştırmamaya dikkat etmelisiniz , ancak şimdi bu kontrollerin bakımı artık o kadar acı verici değil. Örneğin, mevcut bir ücretli özelliği ücretsiz hale getirmek istediğinizde neyi değiştirmeniz gerektiği konusunda daha iyi bir kontrole sahipsiniz (ya da tam tersi).

Son olarak , özellik giriş noktaları / geçiş noktaları hakkında konuştuğu, Fowler'in özellik geçişleri hakkındaki blog makalesine bir göz atalım . Bir merkezi noktadan bahsedeyim:

Yeni özellik kodundaki her kod yolunu bir geçişle korumaya çalışmayın, yalnızca kullanıcıları oraya yönlendirecek giriş noktalarına odaklanın ve bu giriş noktalarını değiştirin.

Genel bir strateji olarak, kullanıcı arayüzüne odaklanın ve çeklerinizi, belirli bir özelliğin görünmesi veya kaybolması için gereken minimum sayıda nokta ile sınırlandırın. Bu, kod tabanınızı gereksiz karmaşa olmadan temiz tutmalıdır.


5
Temel olarak IsFreeVersion'ı FeaturexEnabled ile değiştirdiniz, arama sayısını azaltmadınız. Tam olarak bu durumda olmasa da, her zaman kullanıcının görmemesi gereken seçenekleri devre dışı bırakarak menü oluşturma üzerine benzer şeyler ele aldım. Çoğunlukla bu form oluşturma aşamasındadır, ancak bazen bir açılır menü hazırlarken yapmak zorunda kaldım.
Loren Pechtel

1
@LorenPechtel: Cevabımı daha dikkatli okumalısınız. Aslında koşullu test sayısını azaltmak için iki şeyden bahsettim , bunlardan biri DRY prensibi, biri UI'deki testlere odaklandı. Daha da önemlisi, gibi belirli olmayan ve bayrak haritalama isFreeVersioniçin spesifik en bu testlerin ağrının özelliği parametreleri uzaklaşmaların - aslında mantıklı başlayacak ve bir daha bakım karmaşa üretemezler.
Doc Brown

6

Bana öyle geliyor ki, sorunuz Özellik Değiştirme Desenini uygulayarak oldukça iyi bir şekilde çözülebilir .

Çoğu zaman olduğu gibi, Pete Hodgson bir makalede bu modeli uygulayabileceğiniz tüm senaryoları, yapabileceğimden çok daha iyi açıkladı.

Bu modeli destekleyen bazı kütüphaneler de vardır. Java FF4J ile çalışma deneyimi vardı ama sen yazın tahmin ediyorum:

feature toggle <whatever language you prefer>

... herhangi bir arama motorunda birkaç çözüm elde edersiniz.


2

Bunu başarmanın birden fazla yolu var. Basit ve basit bir yol, birçok makalede sağlanan Özellik Geçiş Desenini kullanmaktır . Bir sonraki yaklaşım, takılabilir özellikler için tasarım yapmakla ilgilidir. Hem Android hem de IOS uygulama içi ödemelere sahiptir. Bu ödeme ile birlikte bir indirme potansiyeli vardır.

Servlets, JAMES Mailets ve hatta IDE eklentilerine baktığınızda, hepsi bir eklenti mimarisi kavramını kullanır:

  • Uygulamanızın nasıl kullanılacağını bildiği bir arayüz tanımlayın. Bu arayüz, temas noktalarına eklenti uygulamak için kendini uygulamanızın navigasyonuna ve diğer herhangi bir uygulamaya enjekte etmenin bir yolunu sağlamalıdır.
  • Uygulamanızın başlangıçta okuyacağı bir yol ayarlayın (çalışma zamanı eklenti yönetimi çok daha zordur)
  • Bir eklenti varsa (Java Jar dosyası gibi), uygulama ya eklenti arayüzünün uygulamasını bulmak için bildirimi okur veya arabirimi uygulayan bir sınıfı tarar.
  • Bu sınıf bulunduğunda, somutlaştırılır ve yeni özellikleri entegre etmek için uygun yöntemler çağrılır.

Bunun da size izin verdiği şey, farklı kitleler için farklı özellik sınıflarına sahip olma fırsatıdır. Kullanıcılar yalnızca kendilerine ödenen özelliklere sahiptir.

Uygulama kodunuz bir kod tabanı olarak korunur ve eklentiniz ayrı bir kod tabanıdır - ancak yalnızca eklentiyle ilgili olan parçaları içerir. Uygulama mevcut olduklarında eklentilerle nasıl başa çıkılacağını bilir ve eklenti sadece arayüzle nasıl etkileşime gireceğini bilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.