مسئلهای که باید حل میکردم
وقتی هستهٔ دلو را شروع کردم، میخواستم یک کارت در حکم و جوکر همان هویت منطقی را داشته باشد. تغییر تصویر نباید کارت تازهای داخل دست بسازد یا انتخاب قبلی را جابهجا کنه.
پیادهسازی در نسخهٔ فعلی
CardInstance دادهٔ CardData را نگه میدارد و در سازنده یک InstanceId مستقل میسازد. Suit و Rank از داده خوانده میشوند؛ شناسه به نمونهٔ زنده تعلق داره، نه تصویر کارت.
تصمیم و هزینهٔ طراحی
این جداسازی یک شیء بیشتر میسازد، اما تفاوت تعریف مشترک و نمونهٔ داخل مسابقه را روشن میکنه. دو نمونه با تصویر یکسان لزوماً همان کارت نیستند.
مرزهای فعلی
شناسهٔ تازهٔ سازنده راهکار بازیابی کامل یک مسابقه نیست. این کلاس بهتنهایی سریالسازی دستها یا همگامسازی شبکه را فراهم نمیکنه.
هویت هنگام جابهجایی کارت
سناریوی سادهای را در نظر بگیر: بازیکن یک کارت را انتخاب کرده و همزمان رابط، دست او را مرتب میکنه. اگر انتخاب فقط با شمارهٔ خانهٔ آرایه ذخیره بشه، بعد از مرتبسازی همان شماره میتواند به کارت دیگری اشاره کنه. InstanceId راهی برای حرف زدن دربارهٔ خود نمونه فراهم میکنه. در CardInstance این مقدار با Guid.NewGuid ساخته میشود؛ بنابراین مصرفکننده میتواند انتخاب را به کارت نسبت دهد و جای نمایشی را جداگانه پیدا کنه. این توضیح یک کاربرد معماری هست، نه ادعای اینکه همهٔ اجزای رابط از همین الگو استفاده میکنند.
مرز دیگر، تفاوت Data با خود CardInstance هست. دو کارت میتوانند به یک تعریف CardData اشاره کنن و در عین حال دو شناسهٔ متفاوت داشته باشند. Suit، Rank و IsJoker از همان تعریف خوانده میشوند و کلاس نسخهٔ جداگانهای از این مشخصات نمیسازد. این انتخاب از ناسازگاری مشخصات تکراری جلوگیری میکنه، اما معنایش این هست که دادهٔ مرجع باید با احتیاط مدیریت بشه. readonly بودن فیلد data جلوی تعویض مرجع را میگیرد؛ بهتنهایی تضمین نمیکنه که تمام محتوای شیء مرجع در بخشهای دیگر غیرقابل تغییر باشد.
در سازنده نیز ورودی null با ArgumentNullException رد میشود. برای دلو این رفتار مفید هست، چون کارت بیتعریف نباید تا لحظهٔ نمایش یا محاسبهٔ برنده پیش برود و تازه آنجا خراب بشه. از طرف دیگر، سازنده هیچ ورودی برای بازگرداندن یک شناسهٔ قبلی نداره. اگر روزی ذخیرهٔ مسابقه یا دریافت کارت از شبکه لازم بشه، باید سیاست هویت بازسازیشده را جداگانه طراحی کرد. ساختن دوبارهٔ یک کارت با همان خال و رتبه، همان نمونهٔ قبلی را برنمیگرداند و ارجاعهای قدیمی را هم خودکار معتبر نمیکنه.
چیزی که از این مرحله یاد گرفتم
برای من، هویت کارت از همین مرز شروع شد. وقتی بعداً انتخاب و انیمیشن پیچیدهتر شدند، توانستم دربارهٔ همان نمونه حرف بزنم، حتی وقتی جای آن در رابط تغییر کرده بود.
مثال عملی هویت کارت
برای فهم عملی هویت کارت، یک مثال آموزشی را قدمبهقدم دنبال کنیم. دو کارت با ظاهر یکسان را با خال و رتبهٔ متفاوت مقایسه کن و بعد اسکین هر دو را عوض کن. پیش از اجرا، وضعیت آغاز را روی کاغذ بنویس؛ مشخص کن چه چیزی میتواند تغییر کند و چه چیزی باید ثابت بماند. بعد فقط همین مسیر را اجرا کن. این مثال گزارشی از آمار کاربران یا قابلیت تازهٔ منتشرشدهٔ دلو نیست؛ تمرینی برای روشن کردن تصمیم طراحی همین مطلب است.
خطای رایج و علت آن
اگر منطق از نام فایل تصویر هویت بگیرد، عوضکردن اسکین میتواند نتیجهٔ جفتسازی را خراب کند. این خطا معمولاً وقتی پنهان میماند که فقط مسیر موفق و ظاهر نهایی را ببینیم. برای پیدا کردن علت، آخرین وضعیت درست را از نخستین وضعیت نادرست جدا کن و ببین تغییر دقیقاً در کدام مرز رخ داده است. تعریف کارت، نمونهٔ کارت در دست و تصویر نمایشی سه مسئولیت جدا هستند. اگر این تفاوت در قرارداد مشخص نباشد، اصلاح یک نشانه ممکن است همان مسئله را در بخش دیگری دوباره ایجاد کند.
چطور نتیجه را بررسی کنیم؟
آزمون باید ثابت کند تعویض تصویر هیچ اثری روی مقایسهٔ کارت و قوانین ندارد. اجرای یکباره برای نتیجهگیری کافی نیست؛ یک بار مسیر معمول و بار دیگر همان موقعیت را با ورودی مرزی یا تکرار اقدام بررسی کن. اگر نتیجه فرق دارد، ورودی و شرایط اجرا را همراه خروجی نگه دار تا مقایسه قابل بازسازی باشد. جدول زیر خلاصهٔ مشخصات همین سناریو است و برای ثبت نتیجهٔ بررسی به کار میآید.
| بخش بررسی | آنچه باید ثبت شود |
|---|---|
| موقعیت آزمایشی | دو کارت با ظاهر یکسان را با خال و رتبهٔ متفاوت مقایسه کن و بعد اسکین هر دو را عوض کن. |
| ریسک اصلی | اگر منطق از نام فایل تصویر هویت بگیرد، عوضکردن اسکین میتواند نتیجهٔ جفتسازی را خراب کند. |
| روش بررسی | آزمون باید ثابت کند تعویض تصویر هیچ اثری روی مقایسهٔ کارت و قوانین ندارد. |
| مرز نتیجهگیری | تعریف کارت، نمونهٔ کارت در دست و تصویر نمایشی سه مسئولیت جدا هستند. |
پرسشهای کاربردی دربارهٔ هویت کارت
از کجا شروع کنم؟
از همان موقعیت محدود این مطلب شروع کن: دو کارت با ظاهر یکسان را با خال و رتبهٔ متفاوت مقایسه کن و بعد اسکین هر دو را عوض کن. ابتدا نتیجهٔ مورد انتظار را مشخص کن و بعد سراغ پیادهسازی یا ابزار برو. وقتی مسیر پایه قابل توضیح و بررسی شد، میتوان حالتهای بیشتری اضافه کرد. ساخت همهٔ حالتها از ابتدا، فهم علت خطا را سختتر میکند.
چه زمانی میتوانم بگویم این بخش درست کار میکند؟
زمانی که رفتار در موقعیت تعریفشده با قرارداد سازگار باشد و محدودیتهای آن روشن بمانند. آزمون باید ثابت کند تعویض تصویر هیچ اثری روی مقایسهٔ کارت و قوانین ندارد. موفقیت در این آزمون دربارهٔ همان سناریو شاهد میدهد؛ از آن نمیتوان بدون بررسی دربارهٔ همهٔ دستگاهها، همهٔ قوانین محلی یا همهٔ حجمهای داده نتیجه گرفت. تعریف کارت، نمونهٔ کارت در دست و تصویر نمایشی سه مسئولیت جدا هستند.
برای ادامهٔ همین موضوع، هستهٔ مشترک دلو؛ یک میز برای چند بازی و بازی دلو را ببین. زمینهٔ ساخت این پروژهها و معرفی سازنده در صفحهٔ کیان پاک نعمت آمده است.




