Feature Toggle مکانیزمی برای تغییر قابلیتهای برنامه در زمان اجراست که به توسعهدهندگان امکان میدهد بدون تغییر کد و استقرار مجدد، دسترسی به ویژگیها را مدیریت کنند. برخلاف کامپایل شرطی (ifdef)، toggle در سطح runtime کار میکند و میتواند به صورت پویا تغییر کند. به گفته مارتین فاولر (2024)، feature toggles عنصر کلیدی توسعه trunk-based و تحویل پیوسته هستند. Feature toggle به تیمها انعطافپذیری در مدیریت انتشارها و آزمایشها میدهد.
نکات اصلی
Feature Toggle (سوئیچ قابلیت) — تکنیکی است که در آن کد یک ویژگی جدید در یک ساختار شرطی قرار میگیرد که مقدار یک پارامتر پیکربندی را بررسی میکند. اگر پارامتر true باشد — ویژگی جدید فعال است، اگر false باشد — کد قدیمی اجرا میشود. تفاوت کلیدی با feature flag این است که toggle یک سوئیچ باینری است که بر اساس اصل «روشن/خاموش» کار میکند، بدون قوانین پیچیده هدفگیری و توزیع ترافیک.
Feature toggle به عنوان یک ساختار if معمولی در اطراف ویژگی جدید پیادهسازی میشود. مقدار toggle در پیکربندی برنامه — متغیرهای محیطی، فایل JSON یا پایگاه داده ذخیره میشود. هنگام راهاندازی، برنامه پیکربندی را بارگذاری میکند و از آن برای تصمیمگیری درباره مشاهده ویژگیها استفاده میکند. در سادهترین حالت، تغییر مقدار toggle نیاز به راهاندازی مجدد برنامه دارد، اما در سیستمهای تولیدی، toggles معمولاً از بارگذاری داغ (hot reload) از طریق سرور پیکربندی خارجی یا API پشتیبانی میکنند.
پیادهسازی feature toggle در JavaScript (Node.js) را بررسی میکنیم. سوئیچ در پیکربندی JSON ذخیره میشود و هنگام راهاندازی سرور بارگذاری میگردد. Middleware قبل از هدایت درخواست به handler جدید یا قدیمی، مقدار toggle را بررسی میکند. چنین پیادهسازی امکان افزودن ویژگی جدید به شاخه اصلی کد را بدون مختل کردن کار نسخه فعلی API فراهم میکند.
const config = require("./config.json");
const toggles = {
get(name) {
return config.features[name] ?? false;
},
isEnabled(name, context) {
const toggle = config.features[name];
if (!toggle) return false;
if (toggle.enabled === true) return true;
if (toggle.percentage && context.userId) {
return hashCode(context.userId) % 100 < toggle.percentage;
}
return false;
}
};
const app = express();
app.use("/api/checkout", (req, res, next) => {
if (toggles.isEnabled("new_checkout", req)) {
return newCheckoutHandler(req, res);
}
return legacyCheckoutHandler(req, res);
});
پیت هاجسون از ThoughtWorks سه نوع اصلی feature toggles را بر اساس طول عمر و هدف استفاده دستهبندی میکند. تعیین صحیح نوع toggle به انتخاب مکانیزم ذخیرهسازی و فرایند مدیریت مناسب کمک میکند. هر نوع را در زمینه توسعه موبایل بررسی میکنیم.
Business toggles — طولانیترین سوئیچها هستند. آنها قوانین تجاری را مدیریت میکنند که فقط برای دستههای خاصی از کاربران (ویژگیهای پریمیوم، ویژگیهای منطقهای) در دسترس هستند. چنین togglesهایی ممکن است سالها دوام بیاورند و معمولاً منطق پیچیدهتری نسبت به روشن/خاموش باینری دارند. Release toggles — سوئیچهای موقتی برای پنهان کردن ویژگیهای ناتمام. چرخه زندگی آنها از چند روز تا چند هفته است. پس از تکمیل ویژگی، release toggle از کد حذف میشود. این togglesها اساس توسعه trunk-based هستند و به توسعهدهندگان امکان commit به شاخه اصلی را بدون انتظار برای تکمیل کل ویژگی میدهند.
Experiment toggles برای آزمایشهای A/B و انتشار تدریجی استفاده میشوند. برخلاف release toggles، experiment toggles از توزیع درصدی کاربران و ادغام با سیستمهای تحلیلی پشتیبانی میکنند. آنها ممکن است بیشتر از release toggles (تا چند ماه) دوام بیاورند، اما پس از پایان آزمایش باید حذف شوند. Infrastructure toggles — سوئیچهایی برای مدیریت تغییرات زیرساختی: مهاجرت پایگاه داده، انتقال به ارائهدهنده API جدید، تغییر الگوریتمهای کش. این togglesها نیاز به توجه ویژه به آزمایش دارند زیرا تغییر آنها بر پایداری کل سرویس تأثیر میگذارد.
| نوع toggle | مدت | مخاطب | مثال |
|---|---|---|---|
| Business | ماهها-سالها | بر اساس نقشها/مناطق | ویژگیهای پریمیوم |
| Release | روزها-هفتهها | توسعهدهندگان/QA | صفحه ناتمام |
| Experiment | هفتهها-ماهها | درصد کاربران | آزمایش A/B رابط |
| Infrastructure | روزها-هفتهها | داخلی | مهاجرت DB |
اگرچه اصطلاحات «feature toggle» و «feature flag» اغلب به صورت قابل تعویض استفاده میشوند، تفاوتهای مفهومی بین آنها وجود دارد. درک این تفاوتها به انتخاب ابزار مناسب برای یک کار خاص و جلوگیری از سردرگمی در تیم کمک میکند. تفاوتهای کلیدی و حوزههای کاربرد هر رویکرد را بررسی میکنیم.
Feature toggle — در درجه اول یک مکانیزم فنی است: یک سوئیچ باینری تعبیهشده در کد برنامه. Toggle از طریق پیکربندی مدیریت میشود و زیرساخت خارجی نیاز ندارد. Feature flag — مفهوم گستردهتری است که شامل پلتفرم مدیریت میشود: UI برای پیکربندی، SDK برای ادغام، نظارت بر استفاده، تحلیل و حسابرسی. پرچمها از قوانین پیچیده هدفگیری (بر اساس منطقه، نسخه، دستگاه)، آزمایشهای A/B و حذف خودکار پشتیبانی میکنند. میتوان گفت feature flag تکامل feature toggle است: تیم ابتدا با سوئیچهای پیکربندی ساده شروع میکند و با رشد به یک پلتفرم تخصصی منتقل میشود.
برای تیمهای کوچک و پروژههایی با یک سرویس یا مونولیت، togglesهای پیکربندی ساده کاملاً کافی هستند. اگر ۵–۱۰ توسعهدهنده و همزمان ۱–۲ toggle فعال دارید — پلتفرم خارجی اضافی خواهد بود. پلتفرمهای feature flag (LaunchDarkly، Unleash) زمانی ضروری میشوند که تعداد پرچمهای فعال از ۲۰–۳۰ فراتر رود، تیم ۲۰+ توسعهدهنده داشته باشد، یا مدیریت دقیق دسترسی به ویژگیها برای بخشهای مختلف کاربران مورد نیاز باشد. برای برنامههای موبایل، جایی که بهروزرسانی مشتری روزها طول میکشد، پلتفرمهای feature flag مزیت اضافی دارند — امکان تغییر رفتار برنامه بدون انتشار نسخه جدید.
انتخاب ابزار برای مدیریت feature toggles به اندازه تیم، پشته فناوری و الزامات امنیتی بستگی دارد. گزینهها را از فایلهای پیکربندی ساده تا پلتفرمهای مدیریت صنعتی، از جمله جایگزینهای متنباز بررسی میکنیم.
Feature toggles باید شهروندان درجه یک pipeline CI/CD باشند. در مرحله build، pipeline بررسی میکند که همه release toggles برنامهریزیشده برای حذف در اسپرینت جاری واقعاً از کد حذف شدهاند. در مرحله آزمایش، تستهای ماتریسی با ترکیبهای مختلف toggles اجرا میشوند. در مرحله استقرار، سیستم به طور خودکار پیکربندی toggles را با محیط تولید همگام میکند. ادغام با PagerDuty یا Opsgenie امکان ایجاد هشدارها را هنگام شناسایی stale toggles یا بیشازحد شدن تعداد مجاز toggles فعال فراهم میکند.
برای سناریوهای ساده، پیکربندی JSON در Git با بررسی کد بر روی تغییرات کافی است. گزینه پیشرفتهتر — Togglz (Java) یا Gofeature (Go) — کتابخانههایی که UI حداقلی برای مدیریت toggles اضافه میکنند. برای سیستمهای تولیدی، Unleash (متنباز) با SDK برای همه زبانها و پشتیبانی از استراتژیهای فعالسازی، یا Flagsmith با آزمایش A/B داخلی توصیه میشود. LaunchDarkly استاندارد پروژههای سازمانی با الزامات بالای حسابرسی و انطباق باقی میماند. برای برنامههای موبایل، همه راهحلها SDK بومی با کش و حالت آفلاین ارائه میدهند.
Feature toggles ابزاری دو لبه هستند. بدون انضباط مدیریتی، آنها به بدهی فنی تبدیل میشوند که توسعه را کند میکند و پیچیدگی کد را افزایش میدهد. بر اساس تحقیقات CodeScene (2024)، ۳۵–۵۰٪ از پایگاههای کد حاوی stale toggles هستند — سوئیچهایی که پس از پایان انتشار در کد باقی میمانند. استراتژیهای جلوگیری و رفع چنین بدهی را بررسی میکنیم.
فرایند حذف feature toggle از چهار مرحله تشکیل شده است. اول: اطمینان حاصل کنید که toggle برای ۱۰۰٪ مخاطبان فعال یا برای ۰٪ غیرفعال است (بسته به اینکه کدام شاخه کد باید باقی بماند). دوم: تمام بررسیهای شرطی toggle را از کد حذف کنید و فقط شاخهای را که باید رفتار تولیدی باشد باقی بگذارید. سوم: تعریف toggle را از سیستم ذخیرهسازی (پیکربندی، DB یا پلتفرم) حذف کنید. چهارم: تستها را اجرا کنید تا تأیید شود حذف عملکرد را خراب نکرده است. هر toggle باید دارای مالک و تاریخ حذف برنامهریزیشده باشد که هنگام ایجاد سوئیچ ثبت شده است.
حسابرسی دستی toggles در مقیاس بیش از ۵۰ سوئیچ ناکارآمد است. خودکارسازی بر سه اصل استوار است: بررسی CI (وجود stale toggles باعث مسدود شدن merge میشود)، نظارت (داشبورد با سن هر toggle و وضعیت آن)، هشدارها (اطلاع به مالک در صورت عدم تغییر toggle به مدت N روز). ابزارهای تحلیل ایستای کد (SonarQube، ESLint plugin) میتوانند togglesهایی را که همیشه فعال یا همیشه غیرفعال هستند در کد تشخیص دهند — نشانه آشکار stale toggle. بررسی نهایی — مرور کد، که در آن بازبین باید مطمئن شود که toggle جدید واقعاً لازم است و شاخه کد قدیمی حذف خواهد شد.
package toggles
type Toggle struct {
Name string
Enabled bool
Owner string
CreatedAt time.Time
TTL time.Duration
}
type ToggleManager struct {
store map[string]*Toggle
}
func NewToggleManager() *ToggleManager {
return &ToggleManager{store: make(map[string]*Toggle)}
}
func (m *ToggleManager) IsEnabled(name string) bool {
t, ok := m.store[name]
if !ok {
return false
}
return t.Enabled
}
func (m *ToggleManager) GetStaleToggles() []string {
var stale []string
for name, t := range m.store {
if t.Enabled && time.Since(t.CreatedAt) > t.TTL {
stale = append(stale, name)
}
}
return stale
}
سوالات متداول
اصطلاحات اغلب قابل تعویض هستند، اما از نظر فنی feature toggle یک سوئیچ باینری در کد است (شرط if که پیکربندی را بررسی میکند). Feature flag مفهوم گستردهتری است که شامل پلتفرم مدیریت با UI، SDK، تحلیل و قوانین پیچیده هدفگیری میشود. Toggle زیرساخت خارجی نیاز ندارد، flag معمولاً نیاز دارد.
Release toggles باید طی ۱–۲ هفته پس از پایان انتشار حذف شوند. Experiment toggles — بلافاصله پس از پایان آزمایش A/B. Business toggles نیاز به حسابرسی منظم دارند (هر سه ماه یک بار). توصیه میشود یک بررسی CI تنظیم کنید که merge را مسدود کند اگر در PR یک toggle جدید بدون وظیفه حذف در ردیاب وظایف اضافه شده باشد.
بله، feature toggles به طور فعال در توسعه موبایل استفاده میشوند. ابزار اصلی — Firebase Remote Config که امکان مدیریت پویای سوئیچها را بدون انتشار نسخه جدید برنامه فراهم میکند. جایگزینها: LaunchDarkly SDK برای iOS/Android، Unleash SDK، سرور toggle اختصاصی با REST API. پیادهسازی کش کردن مقادیر برای کار در حالت آفلاین مهم است.
روش اصلی — تست ماتریسی: اجرای همه تستها با toggle فعال و غیرفعال. برای N toggle، تست ماتریسی کامل نیاز به 2^n اجرا دارد، بنابراین در عمل ترکیبهای بحرانی انتخاب میشوند. تستهای واحد باید مقدار toggle را mock کنند. تستهای یکپارچهسازی سناریوهای خاص را بررسی میکنند. در CI مرحلهای اضافه میشود که تستها را با ترکیب تصادفی toggles برای شناسایی تعاملات غیرمنتظره اجرا میکند.
خطرات اصلی: ۱) stale toggles — کد با هر دو شاخه (فعال/غیرفعال) پیچیده و دشوار برای نگهداری میشود؛ ۲) پیچیدگی ترکیبی تست — هر toggle تعداد حالتها را دوبرابر میکند؛ ۳) کد مرده — شاخه قدیمی پس از فعال شدن دائمی toggle در کد باقی میماند؛ ۴) امنیت — سوئیچهای کنترل دسترسی با پیکربندی نادرست آسیبپذیری ایجاد میکنند. همه خطرات با وجود انضباط و خودکارسازی قابل مدیریت هستند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید