PDA

View Full Version : سوال: افزایش سرغت با کانستراکتور



Sina.iRoid
پنج شنبه 28 خرداد 1394, 16:04 عصر
سلام
من کاربرد کانستراکتور رو به طوره کامل می دونم. اما یک سوال ذهنم و مشغول کرده و گفتم که اینجا مطرح کنم.

می خواستم بدونم اگر بخوایم فیلد های یک کلاس و مقدار دهی کنیم، (روش اول)، در کانستراکتور پارامتر هایی و تعریف کنیم و وقتی که آبجکت می سازیم، در همون لحظه مقدار ها رو هم وارد کنیم. و روش دیگه اینکه اصلا از کانستراکتور استفاده نکنیم. یعنی بیایم ابتدا یک آبجکت ایجاد کنیم و بعد با استفاده از اون آبجکت فیلد های کلاس و مقدار دهی کنیم.
می خواستم بدونم که اگر ما از کانستراکتور استفاده کنیم باعث افزایش سرعت برنامه میشه؟ من خودم فک می کنم میشه؟
و اینکه کانستراکتور کاربرد دیگه ای هم داره؟

ممنون میشم اگر راهنماییم کنید :)

محمد فدوی
پنج شنبه 28 خرداد 1394, 17:01 عصر
سلام. اولا اینکه سازنده همیشه باید فراخوانی بشه. منظور شمام احتمالا این بود که به جای استفاده از یه سازنده‌ی با آرگومان، از یه سازنده‌ی بدون آرگومان استفاده کنیم و بعد خصوصیات شیء رو یکی‌یکی بصورت دستی مقداردهی کنیم؛ ولی باید بدونیم که تاوقتی سازنده برای یه شیء فراخوانی نشه اون شیء ساخته نمی‌شه و خالیه.

در مورد سرعتش چندان نمی‌تونم نظر قطعی بدم، نیازه که تست بشه و بنچمارک گرفته بشه. اما می‌تونم بگم به احتمال قریب به یقین استفاده از سازنده سریع‌تره یا حداکثر سرعتای مساوی دارن. البته سرعت و اختلافشون تابع شرایط خیلی زیادیه که اینجا بشون نمی‌پردازیم...

اما در مورد کاربرد سازنده...
اولین دلیل و به نظر من مهمترین دلیل، خوانایی برنامه رو افزایش می‌ده. چرا که همه با خوندن کد زیر، بدون نیاز به هبچ توضیحی منظور رو می‌فهمن، درصورتی که اگه از سازنده استفاده نکنیم باید همین پیاده‌سازی توی دوخط انجام بشه:
Dog puppy = new Dog("Puppy");

یکی از مهمترین اصول شیءگرایی، اینه که کلاس باید تا جایی که ممکنه پیاده‌سازی خودش رو مخفی کنه. استفاده از سازنده یکی از کارای دیگه‌ش اینه که کلاس رو «شیءگراتر» می‌کنه. چرا؟ ساده‌ست! چون خیلی وقتا یه شیء رو می‌شه از چند روش مختلف ساخت. خب زبان‌های برنامه‌نویسی یه راه‌حل خوب دارن! می‌شه چندتا سازنده هم داشت! ولی اگه این مزیت رو کنار بذاریم اولا فردی که از کلاس ما استفاده می‌کنه گاهی اوقات به‌جای یه‌خط کد، مجبور می‌شه ۷الی ۸ خط کد بنویسه تا دستی خصوصیات رو مقداردهی کنه. تازه، باید بدونه چجوری این‌کار رو بکنه چون همونطور که گفتم معمولا یه شیء رو از چندروش می‌شه ساخت.

کاربرد دیگه وقتیه که می‌خوایم به فرزندان کلاس بگیم «مجبورید این خصوصیت رو مقداردهی کنید»! یه مثال بزنیم:

public class Dog {
private String name;
public Dog(String name) {
this.name = name;
}
}

یه کلاس ساده به اسم Dog داریم. وقتی یه کلاس دیگه ازش ارث‌بری کنه «مجبوره» یه فکری به حال name بکنه! حالا یا از سازنده‌ش می‌گیره‌ش یا هرکار دیگه‌ای:


public class Husky extends Dog {
public Husky(String name, [...]) {
super(name);
...
}
...
}


اینجوری تضمین می‌کنیم که یه Dog بی‌نام نمی‌مونه!

کاربرد دیگه‌ای که به ذهن من می‌رسه در مورد خیلی از الگو‌های طراحی یا همون Design Patternهاست. الگوی Immutable رو درنظر بگیر. برای پیاده‌سازی این الگو حتما نیاز به سازنده داریم. چرا که قراره خصوصیات شیء تغییر نکنن. همون کلاس Dog رو درنظر بگیر. اگه هیچ متدی به نام setName برای تغییر نام وجود نداشته باشه و فقط یه متد برای خوندن نام به اسم getName باشه کلاس ما Immutable خواهد بود. اما اگر قرار باشه هروقت که خواستیم یه Dog بسازیم خودمون دستی نامش رو تعیین کنیم، پس باید متد setName رو بنویسیم، پس کلاس Immutable نخواهد بود، پس از کلی از خوبیای این الگو بی‌بهره می‌مونیم!

من فکر می‌کنم دلایل دیگه‌ای هم باشه که الان چیز دیگه‌ای به ذهنم نمی‌رسه. شاید بعدا کامل‌ترش هم کردم.
موفق باشی.

-سیّد-
جمعه 29 خرداد 1394, 18:54 عصر
از توضیحات کامل دوستمون ممنونم.

در مورد سرعت اجرای کد: استفاده یا عدم استفاده از سازنده برای یک کلاس، به خودی خود، تقریباً هیچ تأثیری در سرعت اجرای برنامه نداره (که البته همون طور که دوستمون اشاره کردن، «عدم استفاده از سازنده» به معنی این نیست که کلاس سازنده نداره، جاوا به صورت خودکار یه سازنده‌ی بدون آرگومان برای کلاس شما تولید می‌کنه و اون موقع ساختن شیء فراخوانی می‌شه).
بذارین اینطوری توضیح بدم:
این دو تا کلاس رو در نظر بگیرید:

public class A {
private int x;
public A(int x) {
this.x = x;
}

public int getX() {
return this.x;
}
}

public class B {
private int y;
public B() {
}

public int getY() {
return this.Y;
}

public void setY(int y) {
this.y = y;
}
}

حالا این دو تا استفاده از این کلاس‌ها رو ببینید:

// ساختن یک نمونه از کلاس اول و مقداردهی متغیر آن
A a = new A(10);

// ساختن یک نمونه از کلاس دوم و مقداردهی متغیر آن
B b = new B();
b.setY(10);

این دو تکه کد از نظر سرعت اجرا تقریباً هیچ فرقی با هم ندارن. چند تا دلیل وجود داره. یکی این که مقداردهی به یه پارامتر انقدر سریع هست که اصلاً توی سرعت اجرای کد شما تأثیر نمی‌ذاره (یعنی چند نانوثانیه زمان می‌بره). دیگه این که وقتی JIT دخالت می‌کنه، این دو تا کد هیچ فرقی با همدیگه نخواهند داشت.
اینجا درباره‌ی این موضوع بیشتر توضیح دادم:
http://blog.yooz.ir/?q=node/20