Features
Feature Flags z Remote Config i percentage rollout
馃摉 Przegl膮d
Modu艂 Features umo偶liwia zarz膮dzanie feature flags z obs艂ug膮
Firebase Remote Config, percentage rollout i lokalnych overrides do test贸w.
// 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(key, default: String, description, variants)
Definiuj flag臋 string z opcjonalnymi wariantami.
define(key, default: Int, description, range)
Definiuj flag臋 int z opcjonalnym zakresem warto艣ci.
defineLong(key, default: Long, description)
Definiuj flag臋 long.
defineDouble(key, default: Double, description)
Definiuj flag臋 double.
// 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艣ci
isEnabled(key: String): Boolean
Sprawd藕 czy flaga boolean jest w艂膮czona (uwzgl臋dnia rollout).
getString(key: String): String
Pobierz warto艣膰 string.
getInt(key: String): Int
Pobierz warto艣膰 int (z walidacj膮 range).
getLong(key: String): Long
Pobierz warto艣膰 long.
getDouble(key: String): Double
Pobierz warto艣膰 double.
馃敡 Overrides (testowanie)
override(key: String, value: Any)
Nadpisz warto艣膰 lokalnie (do test贸w).
clearOverride(key: String)
Usu艅 nadpisanie.
clearAllOverrides()
Usu艅 wszystkie nadpisania.
// 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.
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. Jest deterministyczny - ten sam u偶ytkownik zawsze dostanie t臋 sam膮 warto艣膰.
setUserId(id: String)
Ustaw ID u偶ytkownika dla sp贸jnego 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艂ady 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()
}
}