مسئلهای که باید حل میکردم
جایزهٔ روزانه فقط یک دکمهٔ دریافت نیست؛ باید بدانم امروز دریافت شده یا نه و تعریف جایزه معتبر هست یا نه. من زمان را پشت ITimeService گذاشتم تا این مرز روشن باشد.
پیادهسازی در نسخهٔ فعلی
DailyRewardService.CanClaimToday تاریخ ذخیرهشده را با TodayLocal مقایسه میکنه. TryClaimToday فقط بعد از موفقیت GiveReward تاریخ جدید را ذخیره میکنه و تغییر وضعیت را اعلام میکنه.
تصمیم و هزینهٔ طراحی
فرمت تاریخ مستقل از culture هست. با وجود پسوند Utc در نام فیلد قدیمی، رفتار فعلی روز محلی را استفاده میکنه؛ توضیح محصول باید همین رفتار را بگوید.
مرزهای فعلی
این زمان از دستگاه میآید و زمان مورد اعتماد سرور نیست. تغییر ساعت یا منطقهٔ زمانی یک محدودیت واقعی هست؛ همچنین نتیجهٔ claim و نتیجهٔ grant باید با هم خوانده بشن.
سناریوهای بررسی و معنای قرارداد
مرز روز محلی را با یک مثال میشود بهتر دید: دریافت جایزه کمی پیش از نیمهشب و مراجعهٔ دوباره بعد از نیمهشب دو روز تقویمی متفاوت هستند، حتی اگر فاصلهٔ واقعی کوتاه باشد. این رفتار از مقایسهٔ تاریخ میآید و وعدهٔ فاصلهٔ ثابت بیستوچهارساعته نمیدهدد. بنابراین متن صفحه باید همان قاعده را توضیح بدهد. نام قدیمی فیلد با پسوند Utc نیز نباید مبنای توضیح محصول بشه؛ آنچه امروز اجرا میشود مهم هست. جدا کردن منبع زمان پشت رابط به من اجازه میدهد دربارهٔ این مرز مستقل از دکمه و نمایش تاریخ فکر کنم.
نکتهٔ حساستر ارتباط دریافت با توزیع پاداش هست. توزیع سکه میتواند برای نمایش انیمیشن، درخواست را در حافظه نگه داره و موفقیت را پیش از افزایش موجودی برگرداند. سرویس روزانه پس از چنین نتیجهای تاریخ دریافت را ثبت میکنه. پس بستن برنامه در آن فاصله میتواند وضعیتی بسازد که روز دریافتشده ولی سکه هنوز به حساب محلی نرسیده هست. این یک مرز قابل مشاهده در قرارداد فعلی هست، نه ادعای وقوع برای کاربران. بررسی لازم شامل مسیر بدون نمایش، پایان عادی نمایش و قطع فرایند در میانه هست تا معنای موفقیت برای محصول روشن بماند.
برای انتقال قاعده به بازیکن، متن زمان بعدی باید با TodayLocal هماهنگ باشد. نمایش شمارش معکوس بیستوچهارساعته روی قاعدهٔ روز تقویمی وعدهٔ متفاوتی میدهد. همچنین رد شدن تعریف پاداش نامعتبر با دریافت دوبارهٔ امروز یکی نیست و پیام مناسب هر کدوم فرق داره. چنین جزئیات کوچکی باعث میشوند تصمیم سرویس در صفحه قابل فهم بماند و مشکل داده پشت دکمهٔ خاکستری پنهان نشود.
چیزی که از این مرحله یاد گرفتم
برای من، مرز روزانه باید قابل توضیح باشد. نمایش دکمه از CurrentState میآید، ولی گرفتن جایزه از بررسی سرویس؛ عوضشدن ظاهر دکمه نباید به معنای اعطای دوبارهٔ سکه باشد.
مثال عملی جایزهٔ روزانه
اگر بخواهی جایزهٔ روزانه را در یک پروژهٔ کوچک بررسی کنی، بهتر است از یک موقعیت محدود شروع کنی. بازیکن جایزه را میگیرد، صفحه را دوباره باز میکند و ساعت دستگاه را تغییر میدهد. ورودی را ثابت نگه دار و نتیجهٔ مورد انتظار را پیش از اجرای نسخه بنویس. این کار کمک میکند تفاوت میان رفتار منطقی و چیزی که صرفاً روی صفحه دیده میشود روشن بماند. سناریوی این بخش آموزشی است و ادعای نتیجهٔ واقعی یک آزمایش روی کاربران دلو ندارد.
خطای رایج و علت آن
تکیهٔ کامل بر ساعت محلی میتواند دریافت پاداش را پیشبینیناپذیر یا قابل دور زدن کند. این خطا معمولاً وقتی پنهان میماند که فقط مسیر موفق و ظاهر نهایی را ببینیم. برای پیدا کردن علت، آخرین وضعیت درست را از نخستین وضعیت نادرست جدا کن و ببین تغییر دقیقاً در کدام مرز رخ داده است. در نسخهٔ آفلاین محدودیت اعتماد به ساعت را صریح بگو؛ آن را امنیت سرور معرفی نکن. اگر این تفاوت در قرارداد مشخص نباشد، اصلاح یک نشانه ممکن است همان مسئله را در بخش دیگری دوباره ایجاد کند.
چطور نتیجه را بررسی کنیم؟
دریافت تکراری و مرز روز را با زمان مرجع تعریفشده آزمایش کن. اجرای یکباره برای نتیجهگیری کافی نیست؛ یک بار مسیر معمول و بار دیگر همان موقعیت را با ورودی مرزی یا تکرار اقدام بررسی کن. اگر نتیجه فرق دارد، ورودی و شرایط اجرا را همراه خروجی نگه دار تا مقایسه قابل بازسازی باشد. جدول زیر خلاصهٔ مشخصات همین سناریو است و برای ثبت نتیجهٔ بررسی به کار میآید.
| بخش بررسی | آنچه باید ثبت شود |
|---|---|
| موقعیت آزمایشی | بازیکن جایزه را میگیرد، صفحه را دوباره باز میکند و ساعت دستگاه را تغییر میدهد. |
| ریسک اصلی | تکیهٔ کامل بر ساعت محلی میتواند دریافت پاداش را پیشبینیناپذیر یا قابل دور زدن کند. |
| روش بررسی | دریافت تکراری و مرز روز را با زمان مرجع تعریفشده آزمایش کن. |
| مرز نتیجهگیری | در نسخهٔ آفلاین محدودیت اعتماد به ساعت را صریح بگو؛ آن را امنیت سرور معرفی نکن. |
پرسشهای کاربردی دربارهٔ جایزهٔ روزانه
از کجا شروع کنم؟
از همان موقعیت محدود این مطلب شروع کن: بازیکن جایزه را میگیرد، صفحه را دوباره باز میکند و ساعت دستگاه را تغییر میدهد. ابتدا نتیجهٔ مورد انتظار را مشخص کن و بعد سراغ پیادهسازی یا ابزار برو. وقتی مسیر پایه قابل توضیح و بررسی شد، میتوان حالتهای بیشتری اضافه کرد. ساخت همهٔ حالتها از ابتدا، فهم علت خطا را سختتر میکند.
چه زمانی میتوانم بگویم این بخش درست کار میکند؟
زمانی که رفتار در موقعیت تعریفشده با قرارداد سازگار باشد و محدودیتهای آن روشن بمانند. دریافت تکراری و مرز روز را با زمان مرجع تعریفشده آزمایش کن. موفقیت در این آزمون دربارهٔ همان سناریو شاهد میدهد؛ از آن نمیتوان بدون بررسی دربارهٔ همهٔ دستگاهها، همهٔ قوانین محلی یا همهٔ حجمهای داده نتیجه گرفت. در نسخهٔ آفلاین محدودیت اعتماد به ساعت را صریح بگو؛ آن را امنیت سرور معرفی نکن.
برای ادامهٔ همین موضوع، هستهٔ مشترک دلو؛ یک میز برای چند بازی و بازی دلو را ببین. زمینهٔ ساخت این پروژهها و معرفی سازنده در صفحهٔ کیان پاک نعمت آمده است.




