JavaBeans Pattern in Java | الگوی جاوا بین در جاوا
توضیحات جلسه
جزوه و مستندات
مفاهیم کلیدی
- JavaBeans Pattern
رویکردی در ساخت شیء که در آن ابتدا نمونه شیء با استفاده از یک constructor بدون پارامتر ساخته میشود و سپس فیلدهای اجباری و اختیاری از طریق متدهای setter مقداردهی میشوند.
- Inconsistent State
وضعیتی ناپایدار که در آن ساخت شیء بین چند فراخوانی متد تقسیم میشود و قبل از مقداردهی تمام فیلدهای لازم، شیء در حافظه وجود دارد اما دادههای آن ناقص یا نامعتبر هستند.
- Telescoping Constructor Pattern
الگویی سنتی که در آن چندین constructor با تعداد پارامترهای مختلف تعریف میشوند؛ الگوی JavaBeans برای حل خوانایی پایین این الگو ارائه شد اما معایب جدیدی ایجاد کرد.
- Immutability
قابلیت تغییرناپذیری شیء پس از ساخت؛ الگوی JavaBeans بهدلیل وجود متدهای setter عمومی، امکان پیادهسازی کلاسهای immutable را بهطور کامل از بین میبرد.
- Thread Safety
امنیت چندنخی که در الگوی JavaBeans به دلیل ماهیت mutable بودن اشیاء و امکان تغییر وضعیت همزمان توسط چندین thread، بهخطر میافتد.
- Object Freezing
تکنیکی دستی برای قفل کردن شیء پس از پایان فراخوانی متدهای setter به منظور جلوگیری از تغییرات بعدی؛ این روش به دلیل عدم امکان بررسی توسط کامپایلر، مستعد خطای runtime است و در عمل کاربرد کمی دارد.
موارد مصاحبه ای
- مزیت اصلی الگوی JavaBeans نسبت به الگوی Telescoping Constructor چیست؟
خوانایی بالاتر کد در زمان ساخت شیء و عدم نیاز به پاس دادن مقادیر پیشفرض یا تکراری به constructorهای طولانی و تودرتو.
- چرا الگوی JavaBeans خطر ایجاد وضعیت ناسازگار (Inconsistent State) دارد؟
زیرا فرآیند ساخت شیء به چندین دستور مستقل تقسیم میشود و ممکن است قبل از فراخوانی تمام متدهای setter، شیء توسط بخش دیگری از برنامه استفاده شود، در حالی که فیلدهای اجباری آن هنوز مقداردهی نشدهاند.
- چرا الگوی JavaBeans مانع از ایجاد اشیاء Immutable میشود؟
چون برای مقداردهی فیلدها حتماً باید متدهای setter عمومی در کلاس وجود داشته باشند که امکان تغییر وضعیت شیء را در هر لحظه از چرخه حیات آن باز میگذارد.
- چرا اعتبارسنجی پارامترها در الگوی JavaBeans دشوارتر از Constructor است؟
در constructor میتوان تمام پارامترها را در یک مرحله قبل از ساخت شیء اعتبارسنجی کرد؛ اما در JavaBeans اعتبارسنجی وابستگی بین فیلدها امکانپذیر نیست زیرا ترتیب فراخوانی setterها مشخص نیست.
- چرا تکنیک دستی Freezing راهحل مناسبی برای مشکل Mutability در JavaBeans نیست؟
چون کامپایلر هیچ تضمینی نمیدهد که برنامهنویس حتماً متد freeze را قبل از استفاده از شیء صدا بزند و خطاهای حاصل از آن در زمان runtime ظاهر میشوند.
سناریو کاربردی
- پیادهسازی کلاس بر اساس الگوی JavaBeans و نحوه مقداردهی آن
تعریف کلاس با مقادیر پیشفرض و متدهای setter:
public class NutritionFacts {
private int servingSize = -1; // Required; no default value
private int servings = -1; // Required; no default value
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public NutritionFacts() { }
public void setServingSize(int val) { servingSize = val; }
public void setServings(int val) { servings = val; }
public void setCalories(int val) { calories = val; }
public void setFat(int val) { fat = val; }
public void setSodium(int val) { sodium = val; }
public void setCarbohydrate(int val) { carbohydrate = val; }
}
نحوه ساخت شیء و مقداردهی زنجیرهای:
NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);
اگر فراخوانی متد setServingSize یا setServings فراموش شود، شیء cocaCola با مقادیر پیشفرض نامعتبر (-1) در برنامه گردش میکند و کامپایلر هیچ خطایی صادر نخواهد کرد.
بیشتر بدانید
- خطر خطایابی در Inconsistent State
خطاهایی که به دلیل استفاده از شیء ناقص در الگوی JavaBeans رخ میدهند، معمولاً در نقاطی دور از محل ساخت شیء ایجاد میشوند و ردیابی ریشه خطا (root cause) را بسیار سخت میکنند.
- تداخل با اصول کپسولهسازی
ارائه متدهای setter برای تمام فیلدها عملاً کنترل وضعیت داخلی کلاس را از بین برده و کپسولهسازی را تضعیف میکند.
- جایگزین پیشنهادی (Builder Pattern)
برای رفع همزمان مشکل خوانایی Telescoping Constructor و مشکلات ایمنی و Mutability در JavaBeans، استفاده از الگوی طراحی Builder پیشنهاد میشود.
