PDA

View Full Version : متد و توابع استاتیک خوب یا بد؟



mojtaba.baghban
یک شنبه 11 فروردین 1392, 01:24 صبح
یه مقاله (http://kore-nordmann.de/blog/0103_static_considered_harmful.html) خوندم که توضیح میده چرا استاتیک بده؟ بعد توضیح داده که مثلا در برخی جاها استفاده ازش چندان مشکلی نداره.
حالا موندم که کلا از استاتیک استفاده نکنیم یا مثلا کجاها استفاده کنیم.
قبلا واسم سوال بود که چرا yii از استاتیک خیلی کم استفاده می‌کنه مخصوصا جاهایی که به نظر خودم فلان تابع باید استاتیک می‌بود. لاراول هم استفاده از استاتیک رو کم کرده
خواستم نظر شما رو بدونم واینکه یه توضیحی هم بدین
ممنون

rezaonline.net
یک شنبه 11 فروردین 1392, 02:31 صبح
خب هرجایی که باید استفاده بشه استفاده میشه دیگه .
دلبخواهی که نیست .
مثلا جایی استاتیک بزنیم جایی دیگه نه !!!!

mojtaba.baghban
یک شنبه 11 فروردین 1392, 11:09 صبح
خب هرجایی که باید استفاده بشه استفاده میشه دیگه .
آخه اینجوری نیست. بعضی جاها که باید استفاده بشه به دلیل مشکلاتی که استاتیک بوجود می‌آره (http://kore-nordmann.de/blog/0103_static_considered_harmful.html) به ناچار ازش استفاده نمی‌کنن.

rezaonline.net
یک شنبه 11 فروردین 1392, 14:21 عصر
اگه شما بطور کامل تسلط لازم و اطلاعات کافی در مورد استفاده از متد های استاتیک رو داشته باشید میدونید کجا استفاده کنید که چنین مشکلاتی ایجاد نشه .

mojtaba.baghban
یک شنبه 11 فروردین 1392, 14:54 عصر
من چند تا مقاله خوندم که به شدت توصیه کرده بودن که از متد و خاصیت استاتیک بخاطر اینکه نگهداری و تست سیستم رو بشدت کاهش میدن استفاده نکنین.
مثلا همین فریمورک لاراول که خیلی از استاتیک استفاده می‌کنه تو ورژن ۴ استفاده از استاتیک رو بشدت کاهش داده.

rezaonline.net
یک شنبه 11 فروردین 1392, 15:29 عصر
دوست گلم ، دلیل نمیشه که فریم ورکی زیاد یا کم استفاده کرده ، بشه ازش نتیجه گرفت .
برو توی خیابون ببین از هر 100 ماشینی که رد میشه 90 تاش پراید و پیکانه ، میتونی نتیجه بگیری این ماشینا ماشینای خوبی هستن ؟
از همین 100 ماشین ، شاید 2 تاش بنز باشه ، میتونی نتیجه بگیری که بنز ماشین بدیه چون کم استفاده شده ؟

در مورد تست احتمالا منظورتون کلاسهای تست باشه ، حرفتون تا حدودی درست .
اما متدها و متغیرهای استاتیک ، بهترین راه حل برای بهینه سازی هستن .
یک نمونه خیلی ساده شو توی بلاگم توضیح دادم rezaonline.net/blog ، البته متغیر استاتیک هست .
اگر همین تابع بعنوان متد استفاده بشه داخل یک کلاس باید اون هم استاتیک باشه .
یا یک نمونه دیگرش همین الان یک متد استاتیک نوشتم ، خودتون ببینید و تحلیل کنید همینو اگه استاتیک نمینوشتم ممکن بود چقدر کوئری اضافی تحمیل بشه با هر بار آبجکت گرفتن از کلاسش!

class User extends CActiveRecord
{

static public function getAccount($id=0)
{
static $u;
$id = (int) $id;
if( ! empty($u[$id]))
return $u[$id];

return $u[$id] = Yii::app()->db->createCommand()
->select('account')
->from('user')
->where('id=?',array($id))
->queryScalar();

}
}

mojtaba.baghban
یک شنبه 11 فروردین 1392, 16:07 عصر
همین فریمورک yii که خودتون ازش استفاده کردین چرا تو همین کلاس CActiveRecord نمیاد مثلا توابع find و findall و ... رو استاتیک تعریف کنه که مجبور نباشیم از کلاسمون آبجکت بسازیم؟ حتما استاتیک مشکلاتی داشته که همین فریمورک yii اینقدر کم ازش استفاده می‌کنه.

دوست گلم ، دلیل نمیشه که فریم ورکی زیاد یا کم استفاده کرده ، بشه ازش نتیجه گرفت .
درسته ولی وقتی چند کارشناس میان یه مطلبی رو می‌گن لااقل باید دلیلاشون رو شنید. شما دلیلاشون رو بخونید یا قبول می‌کنید و یا اینکه جوابی واسه اشکالاتی که گرفتن می‌ارید و من رو قانع می‌کنید که اونا اشتباه می‌گن
اینم چندتا مقاله در نقد استاتیک
http://kore-nordmann.de/blog/0103_static_considered_harmful.html
http://r.je/static-methods-bad-practice.html

rezaonline.net
یک شنبه 11 فروردین 1392, 16:25 عصر
شما اصلا متوجه منظور بنده نمیشید .
کل حرف من اینه ، تعدد استفاده از متد های استاتیک هیچ ربطی به اشکال داشتن و یا نداشتن نداره .
هر جایی که لازم باشه متد استاتیک استفاده میشه یا نمیشه .

همین فریمورک yii که خودتون ازش استفاده کردین چرا تو همین کلاس CActiveRecord نمیاد مثلا توابع find و findall و ... رو استاتیک تعریف کنه که مجبور نباشیم از کلاسمون آبجکت بسازیم؟ حتما استاتیک مشکلاتی داشته که همین فریمورک yii اینقدر کم ازش استفاده می‌کنه.
آخه اونجا لازم نبوده ، من متوجه نمیشم .
ظاهرا شما دوست دارید اثبات کنید همیشه از متدهای استاتیک استفاده نشه .
و فکر میکنید حرف من اینه که همیشه استفاده بشه .

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

mojtaba.baghban
یک شنبه 11 فروردین 1392, 17:04 عصر
آخه اونجا لازم نبوده ، من متوجه نمیشم .
چرا لازم نبوده؟ اتفاقا خیلی هم لازم بوده. چرا من باید واسه استفاده از تابع findall یه آبجکت از کلاس مثلا User بسازم که بیاد کلی کوئری اضافی به برنامه تحمیل کنه؟ آیا واقعا نیاز هست واسه استفاده از تابع findall یه آبجکت از کلاس داشته باشیم. واقعا نیازی نیست چون ما هیچ وابستگی به متغیرهای نمونه‌ای نداریم. پس چرا yii این کار رو می‌کنه و تابع رو استاتیک نمی‌کنه و واسه اینکه کوئری اضافی به برنامه تحمیل نشه میاد تابع سازنده رو اینجوری تعریف می‌کنه(به if توجه کن)


public function __construct($scenario='insert')
{
if($scenario===null) // internally used by populateRecord() and model()
return;

$this->setScenario($scenario);
$this->setIsNewRecord(true);
$this->_attributes=$this->getMetaData()->attributeDefaults;

$this->init();

$this->attachBehaviors($this->behaviors());
$this->afterConstruct();
}

یا مثلا تو همین کلاس دلیل وجود تابع model چیه؟ غیر از اینه که می‌خواد یه جوری استفاده از توابعی که می‌باید استاتیک بود رو شبیه‌سازی کنه. و واسه مثلا صدا زدن تابع findall اینجوری عمل می‌کنیم

User::model->findall()
به نظر شما بهتر نبود اینجوری باشه

User::findall()
واقعا چرا yii سعی داره از استاتیک استفاده نکنه؟

ظاهرا شما دوست دارید اثبات کنید همیشه از متدهای استاتیک استفاده نشه .
و فکر میکنید حرف من اینه که همیشه استفاده بشه .
نه اتفاقا من خیلی از استاتیک خوشم میاد واسه همین دوست دارم مشکلاتی که بوجود میاره رو بدونم

اینا صرفا چند تا مثال هستن.
فقط دارن کاربرد نشون میدن .
مثالهایی هستند که می‌خوان با استفاده از اونا مشکلاتی که استاتیک ایجاد می‌کنه رو نشون بدن

مطمئن باشید اگر متد های استاتیک انقدر بد بود اصلا پیاده نمیشد .
مطمئن هستم که متدهای استاتیک کاربردهای خودشون رو دارن و من دوست دارم بدونم دقیقا در چه شرایطی مشکل بوجود می‌آرن

rezaonline.net
یک شنبه 11 فروردین 1392, 17:37 عصر
در حقیقت اون الگوی کلاس singleton هست .
بهتره کمی تحقیق کنید

پیشنهادم مطالعه کتاب
php5 power programming هست

mojtaba.baghban
یک شنبه 11 فروردین 1392, 17:46 عصر
در حقیقت اون الگوی کلاس singleton هست .
کدوم؟
جواب سوالام واشکالات وارده به متدها و خاصیت‌های استاتیک رو نگرفتم.

rezaonline.net
یک شنبه 11 فروردین 1392, 23:19 عصر
اول اینکه دستور اولتون اشتباست و باید اینطوری نوشته بشه

User::Model()->findAll()
در این شیوه که به الگوی singleton معروف هست متد Model حاوی یک و فقط یک شی از کلاس User هست و همه جا قابل دسترس هست .
بعد هم سوال شما از بیخ و بن اشتباست پس نمیشه جواب درستی داد.
برای شروع بحث پیشنهاد میکنم نحوه استفاده دقیق متدها و پروپرتی های استاتیک به همراه قوانین رو توضیح بدید تا مثال کاربردی ارائه بدم .

mojtaba.baghban
دوشنبه 12 فروردین 1392, 01:46 صبح
در این شیوه که به الگوی singleton معروف هست متد Model حاوی یک و فقط یک شی از کلاس User هست و همه جا قابل دسترس هست .
اینو می‌دونم که از الگوی singleton استفاده می‌کنه. بحث من سر اینه که چرا اصلا تابع Model وجود داره؟ کاربردش چیه؟ آیا ما هیچوقت از کدی مثل

User::Model()->save()
استفاده می‌کنیم؟ طبیعتا استفاده نمی‌کنیم. بلکه دقیقا واسه صدا زدن توابعی استفاده می‌کنیم که می‌باید استاتیک می‌بود ولی به دلایلی اون توابع مثل findall رو استاتیک نکردن و اومدن یه تابع Model با الگوی singleton تعریف کردن تا یه جورایی شبیه‌سازی کنن ولی حاضر نشدن توابعی مثل findall رو استاتیک تعریف کنن.
اینکه می‌گم خواستن شبیه‌سازی کنن دلیل دارم. اگه شما یه نگاه به توضیحاتی که تو فایل CActiveRecord.php قبل از تعریف تابع model آوردن نگاه کنی نوشته:

/**
* Returns the static model of the specified AR class.
* The model returned is a static instance of the AR class.
* It is provided for invoking class-level methods (something similar to static class methods.)
حالا چرا yii نیومده متدهای سطح کلاس رو استاتیک تعریف کنه؟ مگه غیر از اینه که توابع سطح کلاس رو باید استاتیک بگیریم؟ و اومده تابع model رو ساخته و خودش هم گفته که این تابع واسه صدا زدن متدهای سطح کلاس فراهم شده.

rezaonline.net
دوشنبه 12 فروردین 1392, 13:09 عصر
ظاهرا باید اینجا ORM هم توضیح بدیم .
ببینید چون هر آبجکت از کلاس User یک AR حساب میشه پس نمیشه متدها بصورت استاتیک باشه .
اگه همونو نگاه کنید از متدهای جادویی برای هندل کردن پروپرتی ها (= فیلدهای دیتابیس) استفاده شده ، متدهای جادویی رو نمیشه بصورت استاتیک پیاده کرد .
و خیلی مسائل دیگه .

در حقیقت من بازم از شما خواهش میکنم یک توضیحاتی در مورد توابع و پروپرتی های استاتیک بصورت کامل ارائه بدید تا بتونید تفاوت و کاراییشون رو بهتر درک کنید .

mojtaba.baghban
سه شنبه 13 فروردین 1392, 01:33 صبح
ببینید چون هر آبجکت از کلاس User یک AR حساب میشه پس نمیشه متدها بصورت استاتیک باشه .
چرا نشه استاتیک تعریف کرد خوب هم میشه تعریف کرد همونطور که تو لاراول ۳ متدهایی مثل findall که اونجا اسمش all هست رو استاتیک تعریف کردن. بلکه موضوع اینه که اگر استاتیک تعریف می‌کردن قدرت مانوروشون کم می‌شد. وقتی ما متدی رو استاتیک تعریف می‌کنیم دیگه چندریختی که یکی از المان‌هایی هست که به شی‌گرایی قدرت میده رو دیگه نداریم.

اگه همونو نگاه کنید از متدهای جادویی برای هندل کردن پروپرتی ها (= فیلدهای دیتابیس) استفاده شده ، متدهای جادویی رو نمیشه بصورت استاتیک پیاده کرد .
البته تابع جادویی __callstatic برای هندل کردن توابع استاتیک وجود داره.

در حقیقت من بازم از شما خواهش میکنم یک توضیحاتی در مورد توابع و پروپرتی های استاتیک بصورت کامل ارائه بدید تا بتونید تفاوت و کاراییشون رو بهتر درک کنید .
توضیحی از توابع وخواص استاتیک تو سایت php

Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static can not be accessed with an instantiated class object (though a static method can).
حالا ما واسه صرفه جویی در خافظه توابع سطح کلاس رو استاتیک تعریف می‌کنیم تا مجبور نباشیم از کلاسمون شی بسازیم.
حالا مگر findall یه تابع سطح کلاس نیست پس چرا استاتیک نیست؟
می‌دونم User از کلاس AR مشتق شده. همین که می‌گین

چون هر آبجکت از کلاس User یک AR حساب میشه پس نمیشه متدها بصورت استاتیک باشه .
نه اینکه نشه خوب چرا نشه مگه اگه استاتیک تعریف کنیم چی میشه؟
جواب این سوال میشه همون محدودیت‌هایی که استاتیک واسه برنامه بوجود می‌آره

rezaonline.net
سه شنبه 13 فروردین 1392, 16:09 عصر
چرا نشه استاتیک تعریف کرد خوب هم میشه تعریف کرد همونطور که تو لاراول ۳ متدهایی مثل findall که اونجا اسمش all هست رو استاتیک تعریف کردن. بلکه موضوع اینه که اگر استاتیک تعریف می‌کردن قدرت مانوروشون کم می‌شد. وقتی ما متدی رو استاتیک تعریف می‌کنیم دیگه چندریختی که یکی از المان‌هایی هست که به شی‌گرایی قدرت میده رو دیگه نداریم.

البته تابع جادویی __callstatic برای هندل کردن توابع استاتیک وجود داره.

توضیحی از توابع وخواص استاتیک تو سایت php

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

نه اینکه نشه خوب چرا نشه مگه اگه استاتیک تعریف کنیم چی میشه؟
جواب این سوال میشه همون محدودیت‌هایی که استاتیک واسه برنامه بوجود می‌آره
شما دارید قیاس میکنید .
ببینید کلاس مدل توی Yii از نوع singleton هست ، پس دیگه نرید با چند تا فریم ورک دیگه مقایسه کنید .
بعد هم من الان گیج شدم .
شما بالا میایید میگید از استاتیک استفاده نشه ، الان اومدید میگید استفاده بشه .
تکلیف چیه ؟
:لبخند:

mojtaba.baghban
چهارشنبه 14 فروردین 1392, 01:27 صبح
شما بالا میایید میگید از استاتیک استفاده نشه ، الان اومدید میگید استفاده بشه .
من نمیگم که استفاده بشه یا نشه فقط میگم که تو نت چندتا مقاله خوندم که توصیه کردن که تا اونجا که امکان داره استفاده نکنید و لینکاش رو هم گذاشتم.
هنوز هم پای حرفهایی که تو پستهای قبلی زدم هستم. ظاهرا شما هم سفت و سخت پای حرفاتون هستین.
متاسفانه غیر از شما کسی تو بحث شرکت نکرد که بشه یه نتیجه‌گیری کرد.
به هر حال از اینکه وقت گذاشتی به سوالام جواب دادی ممنونم.

rezaonline.net
چهارشنبه 14 فروردین 1392, 10:26 صبح
مخلصیم.
در اصل ما داریم oop کد میزنیم ، فقط جاهای از استاتیک استفاده میشه که اون متد/پروپرتی در تمامی آبجکت ها باید موجود و تاثیر داشته باشد.
مثلا فکر کنید یک کلاس دیتابیس داریم و میخوایم به هر تعدادی ازش شی بسازیم ، در آخر میخوایم لیست کوئری هایی که ایجاد شده رو ببینیم پس کارمون به استاتیک می افته .
یا فرض کنید یک کلاسی مینویسیم ، یکی از متدها ، کلا خارج از روند فعالیت کلاس هست (مثلا یک متد نیازی هست برای بررسی زوج و فرد) اونو بصورت استاتیک مینویسم .

mojtaba.baghban
چهارشنبه 14 فروردین 1392, 11:51 صبح
فقط جاهای از استاتیک استفاده میشه که اون متد/پروپرتی در تمامی آبجکت ها باید موجود و تاثیر داشته باشد.
ولی به نظر من لزومی در تاثیر داشتن در تمامی آبجکت‌ها نیست بلکه به نظر من جاهایی از استاتیک استفاده می‌کنیم که اون متد مستقل از آبجکت باشه

rezaonline.net
چهارشنبه 14 فروردین 1392, 14:04 عصر
دقیقا خاصیت اصلی متدها و پروپرتی ها استاتیک اینه ، میشه چندین شی گرفت از کلاس ، توی یک شی مقدار دهی کرد ، توی یک شی دیگه فراخوانی .
و و و ...
برای نگه داری لاگهای یک کلاس خاص حرف نداره :چشمک: