PDA

View Full Version : سوال در مورد شی گرایی داشتم خواهشا راهنمایی بفرمایید.



aliarya
سه شنبه 04 فروردین 1394, 18:33 عصر
با سلام به دوستان برنامه نویس:

من در حال یادگیری MVC5 و انتتی کد فرست هستم. حالا این وسط ها توی درکم از شی گرایی به مشکل خوردم. و تا چیزی رو کاملا تجسم نکنم نمیتونم یادش بگیرم.

1- مشکل اساسی با سازنده ها یا constructor ها دارم. به چه کاری میان دقیقا . چرا نباید از سازنده ی پیشفرض استفاده کنم و توی بدنش پراپرتی ها رو فراخوانی کنم. چه موقع باید یک کانستراکتور تعریف کنم؟ تعریف کتابیش رو نمیخوام . میخوام بدونم شما به عنوان برنامه نویس با تجربه و حرفه ای چه موقع اقدام به ساخت سازنده میکنید. چه کمکی بهتون میکنه.
2 - فرض بر اینه که من یک برنامه رو از پایه شروع به نوشتن کردم. الان در کلاس جدیدم نیاز به یک کلاس دارم. در اینجا معمولا کلاس رو نیو میکنن ولی چرا اینهریتش نکنم و بعد پارامترهای جدید رو بهش اضافه نکنم و استفاده کنم. یعنی مثلا از یک حالت هرمی استفاده کنم. پارامتر های پرکابرد رو درون یک کلاس بزارم و هی اینهریت کنم و از روی اون اینهریت شده هم باز اینهریت کنم؟ مشکل کار کجاست؟

3 - در مبحث virtual class و بعد override کردنش مگه همون اینهریت کردن یک کلاس نیست . یعنی وقتی میخوام از یک کلاس استفاده کنیم خب دو نقطه میزاریم بعد همه پارامترهای اون کلاس بیس قابل دست یابی هستن دیگه؟ چرا باید از ویرچوال استفاده کنم؟ دوستان عزیز چه موقع از این الگو استفاده میکنن مزیتش چیه واستون.

و راهی و روشی برای درک این مفاهیم و این رابطه ها بین کلاس ها و نحوه استفاده شون بفرمایید ممنون میشم.


هرچند باعث زحمت و وقت دوستان عزیز میشه از این بابت معذرت میخوام و البته بسیار ممنون.

plus
سه شنبه 04 فروردین 1394, 21:21 عصر
1) همونطور که Constructor موقع ایجاد یک شی فراخوانی میشه و در اون Constructor شی میتونه عملیات مورد نیاز رو انجام بده. اگه منظورتون تفاوت بین این دو حالت هست:

class Foo {
private int value;
public Foo(int value) {
this.value = value;
}
public int Value {
get {
return this.value;
}
set {
this.value = value;
}
}
}
..
..
Foo obj = new Foo(10);
/////////////////////////////////////////
class Foo {
private int value;
public Foo() {
}
public int Value {
get {
return this.value;
}
set {
this.value = value;
}
}
}
..
..
Foo obj = new Foo() {
Value = 10,
};

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

FileStream fs = new FileStream(@"d:\temp\file.txt", FileAccess.Read);

و اصلا مشخصه FileName یا چیزی شبیه این براش در نظر گرفته نشده که شما بخوای به روش دیگری از کلاس استفاده کنی. در طراحی این کلاس در نظر گرفته شده که هر شی فقط و فقط مربوط به یک فایل هست. حداقل یک علت این موضوع ساده کردن طراحی و کار با کلاس هست. نه تنها هر شی فقط برای یک فایل هست، وضعیت هر شی از زمان ایجاد کلاس، در حالت باز (open) هست، تا زمانی که بسته بشه و در وضعیت (close) قرار بگیره. این هم سادگی رو نتیجه میده. بر اساس این طراحی، Constructor پیشفرضی در نظر گرفته نشده چون با این نیازها سازگار نیست. البته به این معنی نیست که نمیشه یک کلاس FileStream به شکل دیگری نوشت.

2) اول اینکه Inerhit کردن کلاس A از کلاس B در صورتی منطقی هست که عبارت "A یک B است" صحیح باشه. دوم اینکه Inherit کردن پیچیدگی هایی ایجاد میکنه که تا زمانی که واقعا نیازی به این کار نباشه نباید استفاده بشه. سوم اینجه در زبانی مثل #C هر کلاس از فقط یک کلاس دیگه میتونه مشتق بشه.

3) منظورتون رو درست متوجه نشدم.

برای متوجه شدن بهتر شئ گرایی کتاب زیاد هست میتونید مطالعه کنید. بخشی از مطالبی که گفتم از بخش 6.3 کتاب Code Compelete 2nd Edition بود. البته کتاب های مختص شی گرایی هم زیاد هستن.

aliarya
چهارشنبه 05 فروردین 1394, 00:37 صبح
- بله دقیقا منظورم این حالت بود. درک میکنم که بعضی از کلاس های بیلت این به این صورت طراحی شدن و باعث سادگی در استفاده میشه. حتی برای خودم هم راحت تره که از این سازنده ها استفاده کنم. نمیدونم کدوم اصولی تره . یعنی وقتی میخوام طراحی کنم توی ذهنم ساختار کدنویسی کلاسی رو بهتره از سازنده استفاده کنم یا نه . به نظرم باید فرقی و دلیلی باشه 2 مثالی که فرمودید یکی با پیشفرض و یکی با پارامتر . چه موقع از اون چه موقع از این استفاه کنم. منظورم رو صزیح بگم چه موقع شما از کانسراکتور پارامتر دار استفاده میکنید. چه موقع ترجیح میدید داخل بدنه پارامتر ها رو مقداردهی کنید.
2 - ممنون متوجه شدم پس تاکیدم روی استفاده از اینهریت فقط در جدول های انتتی برای ایجاد کلاس های بیس میذارم که منطقی تره . به نظرم اینکار شبیه نرمالایز کردن جدول دیتابیس در روش های قدیمیه . در اصل از تکرار با اینهریت جلوگیری میکنیم اگر درست متوجه شده باشم. البته 3 هفته نیس با انتتی آشنا شدم قبلش هم به طور ابتدایی با دیتابیس آشنا بودم ممکنه اشتباه متوجه شده باشم.

3- ایراد از من بود ویرچوال رو با مباحث اینهریتنس کلاس ها قاطی کردم. ولی یه سوال دارم اگه من چند متد virtual داشته باشم سی شارپ از کجا تشخیص میده من کدوم متد رو آورید میخوام بکنم؟ از سیگنیچر استفاده میکنه ؟

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

plus
چهارشنبه 05 فروردین 1394, 16:19 عصر
1 - لیستی از اینکه چه موقعه از این استفاده کنیم چه موقع از اون ندارم. البته ممکنه اصولی در این مورد باشه ولی من تجربی عمل میکنم.
2- به هر حال هرچه کمتر از inheritance استفاده کنید کارتون در اغلب موارد راحتتر میشه. البته به جز مواردی که واقعا نیازه.
3 - بله همونطور که وقتی از بین چند متد با یک نام، یکی رو call میکنید...

به نظر من همونطور که گذاشتن تمام وقت برای مطالعه اشتباهه، گذاشتن تمام وقت برای تجربه کردن و سعی و خطا هم اشتباهه. حالا خودتون بهتر میدونید... اگه هیچی رو نمیخونین حداقل Code Complete رو بخونید. ارزشش رو داره.

ali_md110
چهارشنبه 05 فروردین 1394, 19:16 عصر
سلام
اول سازنده ها را زمانی بکار میبرند که بخواهند از منابع کلاسها استفاده کنند پس وهله سازی بی مورد و زمانی که نیاز به وهله سازی نداریم کار صحیح نیست
مثلا شما یک کلاس را در قسمت گلوبال برنامه New سازی کنید و فقط درون یک تابع استفاده کنید این هدر دادن منابع برنامه و سربار هست پس بهتر هست درون همان متدی که نیاز هست و بلاک مربوطه عمل وهله سازی انجام شود

دوم مباحثی هست بنام Dependency injection یا ترزیق وابستگی که به نظرم کارگشای شما برای حل سازنده های پارامتردار هست
تزریق وابستگی میگه که منابعی که یک کلاس دارد بصورت پارامتر به سازنده کلاس ارسال کنیم و هر زمان این کلاس نیاز به هر پارامتر داشت عمل وهله سازی انجام بگیرد
فرض کنید یک کلاس داریم که دارای 10 پارامتر و در واقع 10 سرویس هست که هر کدام یک سرویس و خدمت به کلاس ما میدهد
با تزریق وایستگی به موقع عمل وهله سازی انجام شده و به موقع تخریب مبشود
شما باید بیشتر مباحث شی گرایی مثل واسطها Interface و کلاسهاس abstract مطالعه کنید

سوم مبحث ارث بری برای موجودیتها یا کلاسهای دارای خواص مرتبط کاربرد دارد و نمیشود بیخودی ارث بری کرد و Entity Framework کاملا از ازث بری پشتیبانی میکند اما اگر به درستی پیاده سازی نشود سیستم دچار سربار شده و کارایی از دست میدهد

aliarya
چهارشنبه 05 فروردین 1394, 20:04 عصر
سلام و تشکر از دوستان .

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

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