PDA

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



alonemm
چهارشنبه 22 دی 1389, 12:51 عصر
باسلام:
فرض کنید من یک کلاس به نام cl دارم.
و میخوام یک شی ازش درست کنم که در روییداد های صفحه ام ازش استفاده کنم.
حلا بهتر توی هر روییداد مثل کلیک یک دکمه این شی ساخته بشه و یا در قسمت بالای فرمم بسازمش:


public partial class aspectformexitmanager : System.Web.UI.Page
{
cod coding = new cod();
مثل بالا؟

کدوم روش بهتره و سرعت لودش بالاتر هست؟
آیا در روش 2 توی هربار که عملیات PostBack انجام میشه این شی دوباره ساخته میشه؟


با تشکر.

Vahid_moghaddam
چهارشنبه 22 دی 1389, 13:29 عصر
در هر بار postback ساخته می شه. وقتی متغیر رو در بدنه کلاس تعریف و new می کنید، همیشه ساخته می شه، حتی وقتی بهش نیاز نیست. اما اگه در بدنه method کلاس رو new کنید، فقط در اجرای اون method ساخته می شه

alonemm
چهارشنبه 22 دی 1389, 16:08 عصر
پس به نظر شما شی رو از کلاس در خود متد بسازم؟

Vahid_moghaddam
چهارشنبه 22 دی 1389, 17:01 عصر
اگه فقط قراره در یک متد استفاده بشه، در همون متد بسازید

Javad_Darvish_Amiry
چهارشنبه 22 دی 1389, 20:54 عصر
سلام
یه کار دیگه هم می تونی بکنی که بد نیست. پیش بینی برای مواقعی که مثلا از 10 تا متد توی صفحه ات، 4 یا 5 تاش از اون کلاس استفاده میکنن ولی معلوم نیست کی؟!!!
اول یه پراپرتی از اون کلاس در نظر بگیر. تو متد get چک کن متغیرت null نباشه




private MyClass _myInstance;
protected MyClass MyInstance{
get{
if(_myInstance == null)
_myInstance = new MyClass();
return _myInstance;
}
}

alonemm
پنج شنبه 23 دی 1389, 14:19 عصر
سلام
یه کار دیگه هم می تونی بکنی که بد نیست. پیش بینی برای مواقعی که مثلا از 10 تا متد توی صفحه ات، 4 یا 5 تاش از اون کلاس استفاده میکنن ولی معلوم نیست کی؟!!!
اول یه پراپرتی از اون کلاس در نظر بگیر. تو متد get چک کن متغیرت null نباشه




private MyClass _myInstance;
protected MyClass MyInstance{
get{
if(_myInstance == null)
_myInstance = new MyClass();
return _myInstance;
}
}



دوست من :
لطفا متن سوال رو دقیق بخونید.
من گفتم داخل صفحه نه در داخل کلاس.

Javad_Darvish_Amiry
پنج شنبه 23 دی 1389, 14:42 عصر
publicpartialclassaspectformexitmanager : System.Web.UI.Page
{
cod coding = newcod();

صفحه اتون چیه؟ مگه غیر از اینه که یه کلاسه که از کلاسی که تو کد بیهایندش هست داره ارث میبره و خود کلاس کد بیهایند هم از کلاس Page؟ خوب شما این پراپرتی رو تو کد بیهایند تعریف کن و چون protected هست هم تو همون کد بیهایند و هم تو به قول شما صفحه بهش دسترسی داری. Type این پراپرتی هم از همون کلاسی باشه که شما میخوای ازش متغیر داشته باشی. تو نمونه کد خودت اسمش cod بود. یعنی شما به جای این که یه متغیر از cod تعریف کنی و مستقیم یا تو سازنده یا تو پیج لود یا تو هر متد جداگانه ازش new بسازی یا برای هر متد یه متغیر ساخته و اونو new کنی، یه پراپرتی برای اون متغیرت با شیوه ای که بالا گفتم بساز، این متغیر وجود داره تو سطح کلاس اما هزینه ای نداره (تو هر PostBack)؛ حالا اگه یه بار یه متودی نیاز بهش داشت، چون به جای دسترسی مستقیم به متغیر داره از یه getter استفاده میکنه، میشه تو منطق اون getter در صورت null بودن از روش new ساخت و تحویل داد. قسمت بهینه اش کجاست؟ اگه حالا تو همون در خواست بیش از یه بار به اون متغیر نیاز بشه دو بار یا چند بار نمونه ساخته نمیشه. امیدوارم تونسته باشم مطلبو باز کنم.

mehrdad201
جمعه 24 دی 1389, 22:05 عصر
publicpartialclassaspectformexitmanager : System.Web.UI.Page
{
cod coding = newcod();

صفحه اتون چیه؟ مگه غیر از اینه که یه کلاسه که از کلاسی که تو کد بیهایندش هست داره ارث میبره و خود کلاس کد بیهایند هم از کلاس Page؟ خوب شما این پراپرتی رو تو کد بیهایند تعریف کن و چون protected هست هم تو همون کد بیهایند و هم تو به قول شما صفحه بهش دسترسی داری. Type این پراپرتی هم از همون کلاسی باشه که شما میخوای ازش متغیر داشته باشی. تو نمونه کد خودت اسمش cod بود. یعنی شما به جای این که یه متغیر از cod تعریف کنی و مستقیم یا تو سازنده یا تو پیج لود یا تو هر متد جداگانه ازش new بسازی یا برای هر متد یه متغیر ساخته و اونو new کنی، یه پراپرتی برای اون متغیرت با شیوه ای که بالا گفتم بساز، این متغیر وجود داره تو سطح کلاس اما هزینه ای نداره (تو هر PostBack)؛ حالا اگه یه بار یه متودی نیاز بهش داشت، چون به جای دسترسی مستقیم به متغیر داره از یه getter استفاده میکنه، میشه تو منطق اون getter در صورت null بودن از روش new ساخت و تحویل داد. قسمت بهینه اش کجاست؟ اگه حالا تو همون در خواست بیش از یه بار به اون متغیر نیاز بشه دو بار یا چند بار نمونه ساخته نمیشه. امیدوارم تونسته باشم مطلبو باز کنم.

دوست عزیز یه مقدار بیشتر توضیح میدی. روش جالبی به نظر میاد. (ممنون از راهنماییهاتون)

Javad_Darvish_Amiry
جمعه 24 دی 1389, 22:30 عصر
اگه دوستان ناراحت نمیشن چشم توضیح میدم:
فرض کنید شما یه کلاس دارید تو برنامه اتون به اسم Personality:


public class Personality{
public Int32 ID { get; set; }
public String Name { get; set; }
}

حالا تو یکی از صفحاتمون میخوایم از این کلاس استفاده کنیم. خوب چند تا راه داره دیگه نه؟ مثلا یه متغیر در سطح کلاس صفحه (اگه صفحه رو لایق کلاس بودن بدونیم :چشمک:) از جنس Personality تعریف کنیم و همونجا تو تعریف new کنیم؛ یا متغیر رو تو پیج لود new کنیم؛ یا برای کلاس صفحه سازنده بنویسیم و اونجا متغیر رو new کنیم؛ یا تو هر متودی که نیاز داشتیم، همونجا یه متغیر بسازیم و new کنیم و هزار تا یای دیگه.
روشی که بنده پیشنهاد دادم این بود که متغیرمون رو تعریف کنیم ولی مقدار بهش ندیم (new نکنیم) در هیچ کدوم از مکان های بالا. بلکه بیایم یه پراپرتی برای اون متغیر تعریف کنیم و تو متود getterش چک کنیم اگه متغیر null بود new کنیم. در هر صورت هم که متود get متغیرمون رو بر می گردونه. حالا موقع استفاده، به جای استفاده از اون متغیر، از اون پراپرتی استفاده کنیم. خیلی ساده است:


public partial class MyPage : Page{

private Personality _person;
protected Personality Person{
get{
if(Object.RefrenceEquals(null, this._person))
this._person = new Personality();
return this._person;
}
}

protected void Page_Load(Object sender, EventArg e){
// TODO
}

protected void btnSubmit_Click(Object sender, EventArgs e){
// TODO
}

// SOME METHODS HERE

protected void MyMethod(){
// WORK WITH "Person" INSTEAD OF "_person"
}
}

موفق باشید.

mehrdad201
جمعه 24 دی 1389, 23:06 عصر
اقای امیری عزیز از شما تشکر میکنم. خواهش میکنم اگه مشکلی نیست و بخاطر اینکه تاپیک دوستمون (استارتر عزیز) از روال اصلی خارج نشه، تاپیک جدیدی ایجاد کنید و این روش رو توضیح بدید. من چند تا سوال دارم که اونجا بپرسم بهتره.

از استارتر هم عذرخواهی میکنم

Javad_Darvish_Amiry
شنبه 25 دی 1389, 00:09 صبح
دوست عزیز من کل مطلب رو بالا با نمونه کد آوردم و اگه بخوام یه تاپیک هم باز کنم باز باید مطلب بالا رو اونجا کپی کنم، نمیدونم قوانین سایت همچین اجازه ای میده یا نه. اگه اشکالی نداشته باشه، چشم، و اگر نه همین جا سوالتون رو مطرح کنید، اگر چیزی بدونم حتما پاسخگو خواهم بود و دوستان دیگه هم حتما کمکتون خواهند کرد. موفق باشید.

alonemm
دوشنبه 27 دی 1389, 20:28 عصر
دوست من :
(اینجا اگه کسی جوابی میده فقط از روی این هست که جوابش مفید و مورد نظر سوال مربوطه باشه اگه خارج از محدوده سوال یا با ادبیات غیر اخلاقی باشه ندادن جواب بهتره این از قوانین تالار هست)

من یک کلاس در پوشه APP_COD تعریف کردم.
بعد توی قسمت کدنویسی فرم هام میخوام از این کلاس یک شی بسازم و از متد های اون استفاده کنم.
حالا من میخوام بدونم اگه در قسمت public کد فرمم که در پست اول گزاشتم یک شی از این کلاس تعریف کنم بهتره یا اینکه در هر روییداد مثل کلیک یک دکمه این شی رو از کلاس بسازم.
حالا اگه روش اول استفاده بشه در هر بار PostBack شدن صفحه این شی ساخته میشه؟
و دوباره لود یا بارگزاری میشه روی حافظه و سرعت لود رو پایین میاره؟

Javad_Darvish_Amiry
دوشنبه 27 دی 1389, 23:20 عصر
اول جواب سوالتون:
در مورد کلیت سوال، شما جوابتون رو تو همون پست های اول گرفتید؛ من فقط میخوام یه شمای کلی بنویسم. اگه شیئتون عضوی از کلاس باشه، چند تا وضعیت پیش میاد. یا همونجایی که تعریفش کردید (متغیری از اون کلاس) بهش مقدار میدید. در این شرایط به محض ساخته شدن کلاس اصلی (یعنی لود صفحه که خود به خود کلاس صفحه ساخته میشه) این شیئ هم مقدار میگیره. یا این که توی پیج لود یا سازنده کلاس صفحه بهش مقدار میدید (new میکنید) که خوب باز تو هر لود وجود خواهد داشت. یا این که نه، اگه توی متودی بهش نیاز داشتید، اونجا بهش مقدار میدید. این آخریه تا اینجا از همه بهینه تره. چون درسته متغیر رو در سطح کلاس تعریف کردم، اما هزینه اش تنها 4 بایت (32 بیت) از حافظه است (برای نگهداری ارجاع) و خود شیئ هزینه ای نداره، تا وقتی که من توی متودی بهش نیاز داشته باشم و به متغیرم مقدار (new) بدم. یه وضعیت دیگه که سوال فرمودید، این بود که متغیر رو تو سطح کلاس تعریف نکنید (شما برای وضعیت اول اصطلاح " قسمت public" رو بکار بردید که حالت های مختلفش رو بالا بررسی کردیم و وضعیت دوم هم:) بلکه تو هر متود (بنا به مثالی که خودتون ذکر کردید مثلا متودی که رویداد کلیک یه دکمه رو هندل میکنه) بیاین و از کلاستون یه شیئ بسازید. این وضعیت یه خوبی داره اینه که هر جا که بهش نیاز نداشتید، شیئی هم ساخته نخواهد شد. در مورد PostBack فرمودید، که باز تو همین توضیحات بالا، هر جا صحبت از لود شده، شامل PostBack و لود عادی صفحه میشه. یعنی اگر در سطح کلاس باشه، چه اولین درخواست و چه پستبک، متغیر مقدار دهی خواهد شد (با شرح وضعیت های مذکور) و هزینه زمان و حافظه رو خواهد داشت و اگر وضعیت دوم باشه، فقط در متودی که بهش نیاز هست، اگر اون متود فراخونی بشه این اتفاق میفته (مثلا باز طبق مثال شما، اگر دکمه X کلیک بشه در غیر این صورت نه.)
این خلاصه کل داستان بود که تو چند پست اول مطرح شد. (تا اینجا فکر نمیکنم اشتباه کرده باشم، اگه هست بفرمایید تا اصلاح کنم).
اما:
بنده هم در راستای دقیقا همین سوال شما، و بدون این که ذره ای بحث رو منحرف کرده باشم، وضعیت سومی رو هم پیشنهاد دادم. به این شکل که متغیر در سطح کلاس (قسمت public) تعریف بشه (درست مثل چیزی که در قسمت اول سوال شما بود) اما مقدار دهی نشه. به جاش بیایم یه پراپرتی برای کپسوله کردن اون متغیر تو همون قسمت public بنویسیم و باقی ماجرا که اگه هم توی زبان قاصر بوده و نتونسته باشم خوب توضیح بدم، از نمونه کدی که گذاشتم، کاملا مشخصه. (این نمونه کد برای یه صفحه فرضی به اسم MyPage بوده، قسمت کدبیهاندش). حالا دو جور میشه به قضیه نگاه کرد. اگه منظورتون از پرسش یافتن بهترین راه حل بوده، خوب به نظر من این روش بهترین راه حل به حساب میاد، و اگه دوستان نظر دیگه دارن هم حتما میشنوم و روشون میتونیم بحث کنیم و به نتیجه برسیم. پس اعتراض شما مبنی بر خارج از محدوده سوال بودن کاملا مردوده. چون در راستای سوال شما بنده یه راح حل دیگه هم ارائه دادم. اما نه، وجه دوم اینه که منظورتون از پرسیدن سوال، دقیقا این بوده که از روش هایی که شما چی گفتین و فقط همون روش ها، کدوم بهتره و حاضر به شنیدن (عرض کردم شنیدن، نه پذیرش، انتظاری برای پذیرش به هیچ عنوان نیست) راه حل دیگه ای برای پرسشتون نیستید، خوب در عین این که کاملا حق دارید همچین انتظاری داشته باشید، و بنده هم به دیده منت میپذیرم، اما این حق رو برای شما قائل نیستم که سلائق خودتون رو به عنوان قوانین سایت مطرح کنید، و مسلما مدیریت سایت انقدر قدرتمند هست (این رو من تو همین چند روزه که اومدم متوجه شدم، تعجب میکنم که شما با این سابقه عضویت چطور هنوز متوجه نشدید) که اگر من جایی از قوانین عدول کردم، پستم رو پاک کرده و بهم تذکر بدن.
اما در پایان:
برادر خوبم، استاد بزرگوار من، بنده دو بار تو همین تاپیک، خیلی رسمی و جدی و صمیمی عرض کردم، اگه جایی هتک حرمت و بی احترامی ای کردم، کاملا غیرعمدی بوده و از صمیم قلب عذرخواهی میکنم. اما شما ظاهرا شمشیرو از رو بستی و کوتاه هم نمیای. در مورد پستهای بنده چندین بار خورده گرفتی که بیرون از موضوع تاپیکه، که بنده به هر زبونی که بلد بودم خدمتتون توضیح دادم که کاملا اتفاقا در راستای سوال حضرتعالی بوده. (مگه این که سوالتون چیزی غیر از پاراگراف اول این پست و وضعیت های ذکر شده بوده باشه یا منظورتون این بوده باشه که پیشنهاد نو ممنوع که مفصلا خدمتتون توضیح دادم).
صفت ادبیات غیر اخلاقی رو به پست های بنده دادید، که عملا یعنی بنده رو بی اخلاق خوندید.
خیلی ازتون ممنونم، که یکی از وجوه شخصیتی من رو بعد از سی و چند سال زندگی (و البته چندین سال زندگی مجازی رو هم توی سایت ها و تالار های مختلف (البته اگه تالارهایی بازبون غیر فارسی رو هم لایق بدونید) و همه گفتگو ها و مباحث و اصطلاحا پست های مطرح شده رو هم به اون اضافه بفرمایید -هر چند صفت "کاربر تازه وارد" رو تو برنامه نویس دارم با اکانتم یدک میکشم-) بهم نشون دادید. حتما روش فکر میکنم. و در کنارش ضمن تشکر ازتون، پیشنهاد میکنم (فقط پیشنهاده، هر چند شما ظاهرا خیلی دوست ندارید کسی چیزی بهتون پیشنهاد کنه) که حتما در یه فراغت بالی، پست های خودتون رو یکبار مرور بفرمایید - چون پست های من رو هر چند کم، مسلما دوستانی که این مبحث رو دنبال کردن، مرور کردن -. تمام سعیم بر این خواهد بود که منبعد آرامش اکانتتون و تاپیک هاتون رو بهم نریزم.
پاینده و پیروز باشید. برادر کوچک شما، جواد درویش امیری

(از مدیریت محترم هم مصرانه تقاضا دارم، اگه گفتار این برادرمون درسته، قبل از اینکه دیگه رسما بد و بیراه و ناسزا نثارم بشه، ضمن حذف پست هام، بهم هشدار بدن. سپاس از زحمات بی شائبتون)