📖 PrzeglądOverview
Moduł Features umożliwia zarządzanie feature flags z obsługą
Firebase Remote Config, percentage rollout i lokalnych overrides do testów.The Features module enables feature flag management with Firebase Remote Config support, percentage rollout, and local overrides for testing.
// Definiowanie flag
ADict.Features.define("new_ui", default = false, rolloutPercentage = 50)
ADict.Features.define("max_items", default = 10)
// Sprawdzanie
if (ADict.Features.isEnabled("new_ui")) {
showNewUI()
}
val maxItems = ADict.Features.getInt("max_items")
📝 Definiowanie flag
define(key, default: Boolean, description, rolloutPercentage)
Definiuj flagę boolean z opcjonalnym percentage rollout.Define a boolean flag with optional percentage rollout.
define(key, default: String, description, variants)
Definiuj flagę string z opcjonalnymi wariantami.Define a string flag with optional variants.
define(key, default: Int, description, range)
Definiuj flagę int z opcjonalnym zakresem wartości.Define an int flag with optional value range.
defineLong(key, default: Long, description)
Definiuj flagę long.Define a long flag.
defineDouble(key, default: Double, description)
Definiuj flagę double.Define a double flag.
// Boolean z 50% rollout
ADict.Features.define(
key = "new_checkout_flow",
default = false,
description = "Nowy proces checkout",
rolloutPercentage = 50 // tylko 50% użytkowników
)
// String z wariantami
ADict.Features.define(
key = "button_color",
default = "blue",
variants = listOf("blue", "green", "red")
)
// Int z zakresem
ADict.Features.define(
key = "max_retries",
default = 3,
range = 1..10
)
// Long
ADict.Features.defineLong(
key = "cache_duration_ms",
default = 3600000L
)
// Double
ADict.Features.defineDouble(
key = "discount_rate",
default = 0.1
)
📖 Pobieranie wartościGetting Values
isEnabled(key: String): Boolean
Sprawdź czy flaga boolean jest włączona (uwzględnia rollout).Check if boolean flag is enabled (respects rollout).
getString(key: String): String
Pobierz wartość string.Get string value.
getInt(key: String): Int
Pobierz wartość int (z walidacją range).Get int value (with range validation).
getLong(key: String): Long
Pobierz wartość long.Get long value.
getDouble(key: String): Double
Pobierz wartość double.Get double value.
🔧 Overrides (testowanie)
override(key: String, value: Any)
Nadpisz wartość lokalnie (do testów).Override value locally (for testing).
clearOverride(key: String)
Usuń nadpisanie.Remove override.
clearAllOverrides()
Usuń wszystkie nadpisania.Remove all overrides.
// W debug buildzie - wymuś włączenie feature
if (BuildConfig.DEBUG) {
ADict.Features.override("new_checkout_flow", true)
}
// Reset po testach
ADict.Features.clearAllOverrides()
📡 Obserwacja zmian
observe<T>(key: String, listener: (T) -> Unit)
Obserwuj zmiany wartości flagi.Observe flag value changes.
changes: StateFlow<Pair<String, Any?>>
Flow zmian (key to value).
// Callback
ADict.Features.observe<Boolean>("dark_mode") { enabled ->
applyTheme(if (enabled) Theme.DARK else Theme.LIGHT)
}
// Flow
lifecycleScope.launch {
ADict.Features.changes.collect { (key, value) ->
Log.d("Features", "Flag changed: $key = $value")
}
}
📊 Percentage Rollout
Rollout pozwala włączyć funkcję tylko dla części użytkowników.Rollout allows enabling a feature for only a subset of users. Jest deterministyczny - ten sam użytkownik zawsze dostanie tę samą wartość.It is deterministic - the same user always gets the same value.
setUserId(id: String)
Ustaw ID użytkownika dla spójnego rollout.Set user ID for consistent rollout.
// Ustaw user ID (ważne dla spójności!)
ADict.Features.setUserId(currentUser.id)
// Definiuj eksperyment - 20% użytkowników
ADict.Features.define(
key = "experiment_new_onboarding",
default = false,
rolloutPercentage = 20
)
// Użycie
if (ADict.Features.isEnabled("experiment_new_onboarding")) {
showNewOnboarding()
ADict.Analytics.log("experiment_variant", "new_onboarding" to "enabled")
} else {
showOldOnboarding()
ADict.Analytics.log("experiment_variant", "new_onboarding" to "control")
}
💡 PrzykładyExamples praktyczne
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
ADict.init(this, BuildConfig.DEBUG)
setupFeatureFlags()
}
private fun setupFeatureFlags() {
// UI Features
ADict.Features.define("dark_mode_enabled", default = true)
ADict.Features.define("new_navigation", default = false, rolloutPercentage = 30)
// Limits
ADict.Features.define("max_downloads", default = 5, range = 1..20)
ADict.Features.define("cache_size_mb", default = 100)
// A/B Tests
ADict.Features.define("checkout_variant", default = "classic",
variants = listOf("classic", "one_page", "express"))
// Kill switches
ADict.Features.define("enable_chat", default = true)
ADict.Features.define("enable_push", default = true)
}
}
// Użycie w kodzie
fun loadData() {
val maxItems = ADict.Features.getInt("max_downloads")
// ...
}
fun showCheckout() {
when (ADict.Features.getString("checkout_variant")) {
"one_page" -> showOnePageCheckout()
"express" -> showExpressCheckout()
else -> showClassicCheckout()
}
}