گفتگو هایی در باب سی شارپ

the_king

مدیرکل انجمن
آها خیلی ممنون .
ولی همونطور که میدونید ، از این دست اعضایی که به درد یک کلاسِ خاص نمیخوره (که جریانش را در پست قبلی توضیح دادم) و صرفا در ارتباط با View هست که معنا پیدا میکنه ، در طول پروژه ، زیادتر و زیادتر میشن .

در واقع نیازهای معماری MVVM هست که این نیازِ اضافی برای این نوع اعضا را بوجود میاره . (چون در معماری غیر MVVM ، فرضا همون کد در تاپیک wpf ، در همون View بود و لازم به جدا شدن نداشت) .
اگر بخواهید اصول شی گرایی رو رعایت کنید همچنان هر چیزی که مربوط به View هست الزاما یکجا قرار نمیگیره، چه MVVM باشه و چه نباشه. فرضا کپسوله سازی جزو مبانی شی گرایی است، مستقل از اینکه معماری MVVM است یا نیست، در معماری های دیگه هم تفکیک صورت میگیره.
پس به نظرتون چطوره یه کلاس در Model بنام ExteraMemberForMVVM تعریف کنم تا این اعضاهایی که به درد یک کلاس خاصی نمیخوره و صرفا در پروژه ی MVVM (و در کد تاپیک wpf که دادم ، در ارتباط با View) هست که معنا پیدا میکنه را در اون تعریف کنم؟
طراح پروژه شما من نیستم که نظر من رو بپرسید. "اصول برنامه نویسی شی گرا" رو جستجو کنید و مطالعه کنید، می بینید که محتویات کلاس موضوع مشترکی دارند، کلاس یک انباری نیست که هر چیزی که جایی براشون پیدا نمی کنید داخلش بریزید، تفکیک موضوعی مهم ئه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
طراح پروژه شما من نیستم که نظر من رو بپرسید. "اصول برنامه نویسی شی گرا" رو جستجو کنید و مطالعه کنید، می بینید که محتویات کلاس موضوع مشترکی دارند، کلاس یک انباری نیست که هر چیزی که جایی براشون پیدا نمی کنید داخلش بریزید، تفکیک موضوعی مهم ئه.

خیلی ممنون استاد .
اصول برنامه نویسی شی گرا را بلدم .
واسه ی همین این سئوال را مطرح کردم .
الان در یک متد که در تاپیک wpf دادم ، باید برای تولیدِ آرایه ای از رشته های مورد نظر ، ۲ تا متد دیگه در model ایجاد کنم .

حالا در کدوم یک از اون دو کلاسم به این اعضا ربط دارن؟
هیچ کدوم.

هیچ کدوم هم که ربط نداشته باشن ، پس اصول شی گرایی رعایت نشده .

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

از طرفی هم نمیتونم فرضا تا آخرِ پروژه که ۱۰۰ تا از این متدها را خواستم به model ام منتقل کنم ، در ازاش ۱۰۰ تا کلاس بسازم .

پس نهایتا باز هم این سئوال پابرجاست که بهترین راه حل برای این نوع اعضا چیه ؟
اصلا شما باشین ، چی کار میکنین؟
یعنی اون متدی که در تاپیک wpf دادم را بخواین بخشی از متدی که آرایه ای از رشته را تولید میکنه را جدا کنین و به model تون منتقل کنین ، به چه نوع از کلاسِ model تون منتقل میکنید؟
فرضا از متد استاتیک استفاده میکنید یا روش یا کلاس دیگه؟
کلا روش تون چیه برای این راهکار؟

تشکر
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
اصول برنامه نویسی شی گرا را بلدم .
واسه ی همین این سئوال را مطرح کردم .
الان در یک متد که در تاپیک wpf دادم ، باید برای تولیدِ آرایه ای از رشته های مورد نظر ، ۲ تا متد دیگه در model ایجاد کنم .

حالا در کدوم یک از اون دو کلاسم به این اعضا ربط دارن؟
هیچ کدوم.

هیچ کدوم هم که ربط نداشته باشن ، پس اصول شی گرایی رعایت نشده .

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

از طرفی هم نمیتونم فرضا تا آخرِ پروژه که ۱۰۰ تا از این متدها را خواستم به model ام منتقل کنم ، در ازاش ۱۰۰ تا کلاس بسازم .

پس نهایتا باز هم این سئوال پابرجاست که بهترین راه حل برای این نوع اعضا چیه ؟
اصلا شما باشین ، چی کار میکنین؟
یعنی اون متدی که در تاپیک wpf دادم را بخواین بخشی از متدی که آرایه ای از رشته را تولید میکنه را جدا کنین و به model تون منتقل کنین ، به چه نوع از کلاسِ model تون منتقل میکنید؟
فرضا از متد استاتیک استفاده میکنید یا روش یا کلاس دیگه؟
کلا روش تون چیه برای این راهکار؟

تشکر
اگر اصول برنامه نویسی شیء گرا رو بلد باشید طوری روال ها رو تقسیم می کنید که هر قسمت در بخش مناسب قرار بگیره.
فرضا متدی که حجم رو از بایت به یک واحد دیگه تبدیل می کنه چرا در VssBackup ئه؟ تبدیل حجم از بایت به رشته چه ارتباطی با وظایف VSS داره؟
یا چرا لیست درایو های NTFS رو کلاس ExtensionMethodViewModel میده؟
وقتی هر چیزی رو در جای نامناسبی قرار بدهید طبعا برای ایجاد روال ارتباط های نامناسبی ایجاد می کنید که وابستگی بین بخش هایی بوجود میاره که اساسا بهم ربطی ندارند. فرضا اگر قرار بوده ExtensionMethodViewModel لیست درایو ها رو به View منتقل کنه و واسطه است، باید خروجی اش چیزی باشه که مناسب View ئه. نه DriveInfo مناسب استفاده در View بوده و نه TotalSize اش برای نمایش مناسب بوده. مناسب نبوده که اومده اید بعدش با توسل به VssBackup استخراج داده مناسب View می کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
اگر اصول برنامه نویسی شیء گرا رو بلد باشید طوری روال ها رو تقسیم می کنید که هر قسمت در بخش مناسب قرار بگیره.
فرضا متدی که حجم رو از بایت به یک واحد دیگه تبدیل می کنه چرا در VssBackup ئه؟ تبدیل حجم از بایت به رشته چه ارتباطی با وظایف VSS داره؟

سلامی مجدد
خیلی ممنون استاد .
قبلا بعضی از اعضا و متدها را کاملا موقتی نوشتم . صرفا همه شون را توی کلاس VssBackup گذاشته بودم تا بعدا درست کنم . پروژه هنوز تکمیل نشد . مثلا متد GetFixedNtfsDrives که الان به عنوان extension method برای DriveInfo در کلاس ExtensionMethodForDriveInfo منتقل کردم ، قبلا توی کلاس VssBackup بصورت موقت نوشته بودم .

کلاس VssBackup هم و خیلی های دیگه هنوز اعضاش نوشته نشدن (اون اعضایی که نام بردم) . چون الان بیشتر روی ظاهر (و چیدمان کنترل ها) دارم کار میکنم . صرفا فقط اعضایی از منطق تجاری که برای ساخت ظاهر کاربری لازم هست را دارم میسازم .
اصلا بخاطر اینکه الان دارم اعضاشون را مرتب میکنم (تا هر کدوم در جایگاه شون باشن) ، دارم همین سئوال را میپرسم دیگه .



سئوالم هم همینه :
فرضا همین متد تبدیل حجم به واحد داده (گیگا یا ترا یا مگابایت) ، یا اون متد فرمت شده ای که لیستدرایوهای ثابت شده را برمیگردونه ، هر کدوم معمولا یه تک متد یا تک عضوی هستن که کارشون ربطی به هیچ کلاسی که مینویسم نداره .
اگه واسه ی هر کدوم بخوام کلاس درست کنم ، اولا کلاس های تک عضوی (یا نهایتا دو تا سه عضوی) میشن که اولا هدف خاصی را دنبال نمیکنن و دوما تعداد این کلاس ها خیلی زیاد میشه (تا اینجای کار من حداقل 3 تا از این متدها دارم که کار 2 دسته شون مجزاست . بعدا که قطعا زیادتر میشه) .

این مشکلی هست که حتی توی کلاس های متفاوت بذارم (صرف نظر از اینکه تعداد این کلاس ها خیلی بالا میره) ، اصلا هر کدوم از اون کلاس ها ، هدف خاصی را دنبال نخواهند کرد . صرفا فقط یکی دو تا متد یا عضوی دارن که فراخونی میشن .
اگه هم که توی یه کلاس بذارم ، باز هم هدف خاصی را دنبال نمیکنن و به قول شما انبار هم میشه .

واسه ی من حالا این سئوال پیش اومد که شما هم احتمالا با همین مشکلات در پروژه ها تون برخورد کردین که (در View یا هر جای دیگه) ، صرفا به یک متد (یا چند متدی) نیاز داشته باشید که در کلاس هایی که در Model تون طراحی کردین ، مناسب اونجا نباشه .

اون یک متد را چی کار میکنین؟
در کلاسِ Model تون (فرضا مثل همین VssBackup) که بهش ربطی نداره که توش جا بدین .
بخواین هم جداش کنین ، توی هر کلاسی بذارین ، اون کلاس ، هدف خاصی را دنبال نخواهد کرد . صرفا کلاسی میشه که فقط اون عضو توش قرار گرفته تا فراخونی بشه (که در این صورت فرقی نداره که توی اون کلاس باشه یا در کلاسی مثل VssBackup و ...) چون در هر کجا که قرار بگیره ، اون کلاس ، بخاطر اون عضو ، هدفی را دنبال نمیکنه .
بخواین هم همه ی این اعضا را توی یه کلاس بذارین ، علاوه بر مشکل بالا (یعنی اون کلاس ، هدفی را دنبال نمیکنه) ، مشکلِ ازدهامِ این اعضایی که ربطی به هم ندارن ، هم اضافه میشه (همون انباری که گفتین) .

پس راهکار چیه؟
یعنی راهکاری که شما برای این کار در پروژه هاتون استفاده میکنین ، چیه؟


یا چرا لیست درایو های NTFS رو کلاس ExtensionMethodViewModel میده؟

متد FillComboBoxByDriveInfos که در کلاس InteropWithUI هست و این کلاس هم جزء View هست .
از این به بعد به نام کلاس های زیر دقت کنید چون شبیه به هم هستن :
متد GetFixedNtfsDrives در کلاس ExtensionMethodForDriveInfo قرار داره که لیست درایوهای ثابت در کاربر نهایی را بصورت آرایه ای از DriveInfo ها میده .
این کلاس چون Extension Method ای برای کلاس DriveInfo هست ، کلاسِ استاتیک هست .

کلاس ExtensionMethodViewModel (که ViewModel ای برای کلاسِ ExtensionMethodForDriveInfo هست) هم دقیقا متدی با همین نام داره (متد GetFixedNtfsDrives داره) اما منطق تجاری توش نوشته نشد .
این متد (یعنی متد ExtensionMethodViewModel.GetFixedNtfsDrives) ، صرفا متدِ مورد نظر در Model ام ، یعنی متدِ ExtensionMethodForDriveInfo.GetFixedNtfsDrives را فراخونی میکنه و مقدارش را برمیگردونه .

قوانین MVVM رعایت شده دیگه .
مگه مشکلی وجود داره؟

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

بله .
اما رعایتِ MVVM باعث شده که برای اینکه کوچیکترین وابستگی بین View و Model ام بوجود نیاد ، اون بخش از کدهایی که قبلا در View بودن ، باید جدا بشن و برن توی Model.
این جدا سازی ، و این متدی که قراره از View به Model بره ، الزاما و معمولا به کار Model ، مربوط نمیشه (چون قبلا و کلا جزئی از View بوده و به کارِ View مربوط میشه) که این نوع جداسازی ، همین مشکل را برام بوجود میاره که نمیدونم چی کار کنم با این قضیه و اون تیکه کد را کجا دقیقا ببرم؟
هر جا در Model ببرم ، وصله ی ناجور برای اون کلاس هست .
مثل همون تیکه کدی در متد FillComboBoxByDriveInfos که خروجیِ لیست فرمت شده از درایوهای ثابت را میداد .

فرضا اگر قرار بوده ExtensionMethodViewModel لیست درایو ها رو به View منتقل کنه و واسطه است، باید خروجی اش چیزی باشه که مناسب View ئه. نه DriveInfo مناسب استفاده در View بوده

DriveInfo که مشکلی نداره .
جزء Model ام نیست .
جزء دات نت فریم وورک هست که مشکلی نیست .

فقط اطلاعاتِ نام درایو را نبردم و اطلاعاتِ DriveInfo را منتقل کردم چون بعدا ممکنه لازم باشه که در View ، به بعضی از اعضاش هم نیاز داشته باشم . گفتم باز دوباره کاری نشه .
اشکالی هم فکر نکنم برای قضیه ی MVVM باشه . داره مگه؟

و نه TotalSize اش برای نمایش مناسب بوده.

مناسب نبوده که اومده اید بعدش با توسل به VssBackup استخراج داده مناسب View می کنید.

این دو تیکه را دقیقا متوجه نشدم .
اگه منظورتون اینه که کلاس VssBackup ، جای مناسبی برای متد ConvertByteToDataUnit نیست ، تقریبا بله و احتمالا بعدا جا به جاش میکنم (هر چند ، این عضو هم حدودا جزء همین مشکلی میشه گفت هست که مطرح کردم) .

اما اگه منظورتون اینه که ساز و کارِ View ام را جوری باید بچینم که به متد ConvertByteToDataUnit اصلا نیازی نداشته باشم ، ربط خاصی نداره . من به خروجی این متد نیاز دارم .
کلا دقیقا متوجه نشدم منظور این تیکه تون را .

تشکر استاد .
 

the_king

مدیرکل انجمن
سلامی مجدد
خیلی ممنون استاد .
قبلا بعضی از اعضا و متدها را کاملا موقتی نوشتم . صرفا همه شون را توی کلاس VssBackup گذاشته بودم تا بعدا درست کنم.
اگر قرار باشه بعدا درست کنید که میشه ساختمونی که جای ستون هاش اشتباه بوده و بعدا که رسیدید به طبقه پنجم تازه میخواهید درستش کنید. اگر قراره یک کد شیء گرا بنویسید باید از همون اول اصول شی گرایی رو رعایت کنید.

پروژه هنوز تکمیل نشد . مثلا متد GetFixedNtfsDrives که الان به عنوان extension method برای DriveInfo در کلاس ExtensionMethodForDriveInfo منتقل کردم ، قبلا توی کلاس VssBackup بصورت موقت نوشته بودم.
کلاس VssBackup هم و خیلی های دیگه هنوز اعضاش نوشته نشدن (اون اعضایی که نام بردم) . چون الان بیشتر روی ظاهر (و چیدمان کنترل ها) دارم کار میکنم . صرفا فقط اعضایی از منطق تجاری که برای ساخت ظاهر کاربری لازم هست را دارم میسازم .
اصلا بخاطر اینکه الان دارم اعضاشون را مرتب میکنم (تا هر کدوم در جایگاه شون باشن) ، دارم همین سئوال را میپرسم دیگه .

سئوالم هم همینه :
فرضا همین متد تبدیل حجم به واحد داده (گیگا یا ترا یا مگابایت) ، یا اون متد فرمت شده ای که لیستدرایوهای ثابت شده را برمیگردونه ، هر کدوم معمولا یه تک متد یا تک عضوی هستن که کارشون ربطی به هیچ کلاسی که مینویسم نداره .
اگه واسه ی هر کدوم بخوام کلاس درست کنم ، اولا کلاس های تک عضوی (یا نهایتا دو تا سه عضوی) میشن که اولا هدف خاصی را دنبال نمیکنن و دوما تعداد این کلاس ها خیلی زیاد میشه (تا اینجای کار من حداقل 3 تا از این متدها دارم که کار 2 دسته شون مجزاست . بعدا که قطعا زیادتر میشه) .
این مشکلی هست که حتی توی کلاس های متفاوت بذارم (صرف نظر از اینکه تعداد این کلاس ها خیلی بالا میره) ، اصلا هر کدوم از اون کلاس ها ، هدف خاصی را دنبال نخواهند کرد . صرفا فقط یکی دو تا متد یا عضوی دارن که فراخونی میشن .
کد NET. رو با ابزار های مربوطه بررسی کنید، انواع کلاس ها رو پیدا می کنید که فقط یکی دو عضو دارند، چه مشکلی دارند؟ هیچی. ثانیا کلاسی که وظیفه اش تبدیل واحد حجم ئه وظیفه خاصی رو دنبال نمی کنه؟ باید چیکار کنه که هدف خاصی محسوب بشه؟ وظیفه اش تبدیل واحد ئه دیگه.
واسه ی من حالا این سئوال پیش اومد که شما هم احتمالا با همین مشکلات در پروژه ها تون برخورد کردین که (در View یا هر جای دیگه) ، صرفا به یک متد (یا چند متدی) نیاز داشته باشید که در کلاس هایی که در Model تون طراحی کردین ، مناسب اونجا نباشه .
مشکلی به عنوان کلاسی که فقط یکی دو عضو داره وجود نداره، کلاس n تا عضو داره، تعدادش به کارکردش بستگی داره. n دو تا باشه چه مشکلی پیش میاد؟
اون یک متد را چی کار میکنین؟
به سادگی اون یک متد رو در کلاسی با نام مناسب قرار می دهم، لزومی هم نمی بینم که از تنهایی خارج اش کنم، قطعا متد های #C از تنها بودن ناراحت نمیشن. قانون مالیات بر کلاس ها هم نداریم که از بابت زیاد شدنشون زیانی متحمل بشویم.
در کلاسِ Model تون (فرضا مثل همین VssBackup) که بهش ربطی نداره که توش جا بدین .
بخواین هم جداش کنین ، توی هر کلاسی بذارین ، اون کلاس ، هدف خاصی را دنبال نخواهد کرد .
از دید شما هدف خاصی رو دنبال نخواهد کرد، ولی ربطی به اصول برنامه نویسی نداره. از دید شما طراحان NET. کلاس هایی ساخته اند که هدف خاصی رو دنبال نمی کنند. ولی از دید اون طراحان هر کدوم از اون کلاس ها هدفی دارند. اون کسی که
System.Net.Comparer
MS.Internal.Printing.Configuration.UnitConverter
System.Windows.Forms.TableLayoutSettings.StyleConverter
System.Windows.Automation.ScrollItemPatternIdentifiers
MS.Internal.Printing.Configuration.SafeModuleHandle
رو طراحی کرده نه تعداد اعضاء کلاس برایش مهم بوده و نه یکی دو تا عضو بودن رو مشکل میدونسته.
صرفا کلاسی میشه که فقط اون عضو توش قرار گرفته تا فراخونی بشه (که در این صورت فرقی نداره که توی اون کلاس باشه یا در کلاسی مثل VssBackup و ...) چون در هر کجا که قرار بگیره ، اون کلاس ، بخاطر اون عضو ، هدفی را دنبال نمیکنه .
تعابیری که شما بکار می برید ربطی به اصول برنامه نویسی شیء گرا ندارند، شما برای خودتون یک معیار های خوب و بد در نظر گرفته اید که شخصی اند، خاص شما هستند. اون مصداقی که شما برای هدف کلاس در نظر گرفته اید تو دکان هیچ عطاری پیدا نمیشه.
پس راهکار چیه؟
یعنی راهکاری که شما برای این کار در پروژه هاتون استفاده میکنین ، چیه؟
اول برای خودتون تعریف مشکل می کنید، بعد گیر می کنید تو مشکل خود ساخته تون.
کلاس System.Windows.Forms.VisualStyles.VisualStyleElement.Taskbar.BackgroundRight
حتی یک متد هم نداره، فقط یک مشخصه فقط خواندنی داره، هدف مشخصی داره، مشکلی هم نداره. طراحانش برای مشکلی که وجود نداره هم دنبال راهکار نگشتند.
متد FillComboBoxByDriveInfos که در کلاس InteropWithUI هست و این کلاس هم جزء View هست .
از این به بعد به نام کلاس های زیر دقت کنید چون شبیه به هم هستن :
متد GetFixedNtfsDrives در کلاس ExtensionMethodForDriveInfo قرار داره که لیست درایوهای ثابت در کاربر نهایی را بصورت آرایه ای از DriveInfo ها میده .
این کلاس چون Extension Method ای برای کلاس DriveInfo هست ، کلاسِ استاتیک هست .

کلاس ExtensionMethodViewModel (که ViewModel ای برای کلاسِ ExtensionMethodForDriveInfo هست) هم دقیقا متدی با همین نام داره (متد GetFixedNtfsDrives داره) اما منطق تجاری توش نوشته نشد .
این متد (یعنی متد ExtensionMethodViewModel.GetFixedNtfsDrives) ، صرفا متدِ مورد نظر در Model ام ، یعنی متدِ ExtensionMethodForDriveInfo.GetFixedNtfsDrives را فراخونی میکنه و مقدارش را برمیگردونه .

قوانین MVVM رعایت شده دیگه .
مگه مشکلی وجود داره؟
شما باید کلاس ExtensionMethodViewModel رو در جایی بکار ببرید که میخواد با واسطه از Model استفاده کنه، یعنی داخل View. خود ViewModel که نیازی به ExtensionMethodViewModel نداره، پس اگر قراره استفاده از ExtensionMethodViewModel در داخل View باشه، چرا باید DriveInfo ای رو به View تحویل بده که به شکل فعلی اش قابل استفاده در View نیست و تازه بعدش می خواهید با VssBackup پردازش اش کنید؟ اگر DriveInfo به شکل فعلی اش مناسب View باشه باید بدون پردازش اضافی ازش استفاده کنه، که اینطور نیست، پس نباید DriveInfo رو به View منتقل می کردید.
بله .
اما رعایتِ MVVM باعث شده که برای اینکه کوچیکترین وابستگی بین View و Model ام بوجود نیاد ، اون بخش از کدهایی که قبلا در View بودن ، باید جدا بشن و برن توی Model.
این جدا سازی ، و این متدی که قراره از View به Model بره ، الزاما و معمولا به کار Model ، مربوط نمیشه (چون قبلا و کلا جزئی از View بوده و به کارِ View مربوط میشه) که این نوع جداسازی ، همین مشکل را برام بوجود میاره که نمیدونم چی کار کنم با این قضیه و اون تیکه کد را کجا دقیقا ببرم؟
تا جایی که به سوال و جواب های برنامه نویسی مربوط بود براتون توضیح دادم. نه پیشبینی می کنم که در آینده می خواهید از DriveInfo در چه جاهایی استفاده بکنید و نه تمایلی دارم که کد شما رو ویراستاری کنم. این شما هستید که تصمیم میگیرید چه چیزی در چه جایی لازمه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
اگر قرار باشه بعدا درست کنید که میشه ساختمونی که جای ستون هاش اشتباه بوده و بعدا که رسیدید به طبقه پنجم تازه میخواهید درستش کنید. اگر قراره یک کد شیء گرا بنویسید باید از همون اول اصول شی گرایی رو رعایت کنید.

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

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

مشکلی به عنوان کلاسی که فقط یکی دو عضو داره وجود نداره، کلاس n تا عضو داره، تعدادش به کارکردش بستگی داره. n دو تا باشه چه مشکلی پیش میاد؟

به سادگی اون یک متد رو در کلاسی با نام مناسب قرار می دهم، لزومی هم نمی بینم که از تنهایی خارج اش کنم، قطعا متد های #C از تنها بودن ناراحت نمیشن. قانون مالیات بر کلاس ها هم نداریم که از بابت زیاد شدنشون زیانی متحمل بشویم.

از دید شما هدف خاصی رو دنبال نخواهد کرد، ولی ربطی به اصول برنامه نویسی نداره. از دید شما طراحان NET. کلاس هایی ساخته اند که هدف خاصی رو دنبال نمی کنند. ولی از دید اون طراحان هر کدوم از اون کلاس ها هدفی دارند. اون کسی که
System.Net.Comparer
MS.Internal.Printing.Configuration.UnitConverter
System.Windows.Forms.TableLayoutSettings.StyleConverter
System.Windows.Automation.ScrollItemPatternIdentifiers
MS.Internal.Printing.Configuration.SafeModuleHandle
رو طراحی کرده نه تعداد اعضاء کلاس برایش مهم بوده و نه یکی دو تا عضو بودن رو مشکل میدونسته.

تعابیری که شما بکار می برید ربطی به اصول برنامه نویسی شیء گرا ندارند، شما برای خودتون یک معیار های خوب و بد در نظر گرفته اید که شخصی اند، خاص شما هستند. اون مصداقی که شما برای هدف کلاس در نظر گرفته اید تو دکان هیچ عطاری پیدا نمیشه.

اول برای خودتون تعریف مشکل می کنید، بعد گیر می کنید تو مشکل خود ساخته تون.
کلاس System.Windows.Forms.VisualStyles.VisualStyleElement.Taskbar.BackgroundRight
حتی یک متد هم نداره، فقط یک مشخصه فقط خواندنی داره، هدف مشخصی داره، مشکلی هم نداره. طراحانش برای مشکلی که وجود نداره هم دنبال راهکار نگشتند.

آها .
خیلی ممنون استاد .
با این مثال هایی که زدید ، بهتر متوجه شدم استاد .
پس در مواقع مورد نیاز ، کلاسی میسازم که حتی یه عضو هم داشته باشه (هر چند تعدادش شاید خیلی زیاد بشه :) ) .

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

شما باید کلاس ExtensionMethodViewModel رو در جایی بکار ببرید که میخواد با واسطه از Model استفاده کنه، یعنی داخل View.

همین کار را میکنم دیگه .
اون متدِ FillComboBoxByDriveInfos ، درون لایه ی View هست .

خود ViewModel که نیازی به ExtensionMethodViewModel نداره، پس اگر قراره استفاده از ExtensionMethodViewModel در داخل View باشه، چرا باید DriveInfo ای رو به View تحویل بده که به شکل فعلی اش قابل استفاده در View نیست و تازه بعدش می خواهید با VssBackup پردازش اش کنید؟

اگر DriveInfo به شکل فعلی اش مناسب View باشه باید بدون پردازش اضافی ازش استفاده کنه، که اینطور نیست، پس نباید DriveInfo رو به View منتقل می کردید.

پروپرتیِ DriveInfo.Name فقط در کمبوباکس به نمایش در اومده .
اما گفتم DriveInfo شامل بقیه ی اطلاعاتی (مثل حجم درایو و ...) هست که احتمال اینکه بعدا در View ازش استفاده کنم ، زیاده و دیگه اطلاعاتش در دسترسم باشه .
حالا شاید هم این اتفاق نیفته .

ولی بالاخره DriveInfo که جزء لایه ی Model ام نیست .
اون کلاس اکستنشن متدی هم که در Model برای DriveInfo نوشتم را بصورت مستقیم از View بهش دسترسی ندارم (توسط ViewModel این کار را انجام میدم) .

بعدش با VssBackup پردازشش نمیکنم . اون متد ConvertByteToDataUnit در VssBackup را به یه کلاس دیگه منتقل میکنم .
اون بخشی از کدهایی در متد FillComboBoxByDriveInfos که لیست فرمت شده از درایوهای ثابت را برمیگردونه را بصورت متدی در کلاس ExtensionMethodForDriveInfo ذخیره میکنم .
صبر کنین ، کلا تکمیل نشد . دنیایی کار دارن .

تا جایی که به سوال و جواب های برنامه نویسی مربوط بود براتون توضیح دادم. نه پیشبینی می کنم که در آینده می خواهید از DriveInfo در چه جاهایی استفاده بکنید و نه تمایلی دارم که کد شما رو ویراستاری کنم. این شما هستید که تصمیم میگیرید چه چیزی در چه جایی لازمه.

بله .
متوجه شدم .
خیلی ممنون استاد .:rose:
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد
استاد ، میگم در پنجره ی Diagnostic Tools :


1.JPG

چرا اطلاعات قسمت Process Memory ، با اطلاعاتِ ستونِ Heap Size ئه snapshot ای که در بخش Memory Usage گرفتیم ، با هم اون همه اختلاف دارن؟!

Process Memory میگه برنامه ام تا اون لحظه ، 98 مگابایت از حافظه را اشغال میکنه .
اما snapshot ئه دومی (که تقریبا در همون لحظه گرفته شد) ، ستونِ Heap Size اش میگه برنامه ام از 8.3 مگابایت استفاده میکنه .
این همه تفاوت ، برای چیه؟


و هم اینکه کتابخونه هایی که از حافظه های unmanaged هم استفاده میکنن (ما ، بصورت مستقیم ، از حافظه ی unmanaged در برنامه مون استفاده نمیکنیم . بلکه صرفا اون کتابخونه هایی که ازشون استفاده میکنیم ، اونها در دل خودشون از حافظه های unmanaged استفاده کنن) ، این نوع حافظه ها هم اطلاعات میزان استفاده از حافظه شون ، شامل در این snapshot ها میشه؟

حالا اگه بیایم و ما خودمون مستقیما از حافظه ی unmanaged در کدمون استفاده کنیم ، چی؟ در این صورت هم اطلاعات این snapshot ها ، شامل اطلاعات میزان اشغال حافظه های unmanaged مون ، میشن؟

همچنین ، میشه بجای اینکه در snapshot ها ، دنبالِ همه ی اشیایی که از یک نوع استفاده میکنن ، بگردیم (که همه ی اشیا از یک نوعی که در کل برنامه مون وجود داره ، چقدر حافظه را اشغال کردن) ، بجاش ، صرفا دنبال یک متغییری بگردیم تا ببینیم که اون متغییرمون ، چه مقدار از حافظه را اشغال کرده؟ شدنی هست؟ اگه آره ، لینک منبعِ این قضیه یا توضیحی در این باره میدید؟

تشکر استاد .
 

the_king

مدیرکل انجمن
سلامی مجدد
استاد ، میگم در پنجره ی Diagnostic Tools :


مشاهده پیوست 114378

چرا اطلاعات قسمت Process Memory ، با اطلاعاتِ ستونِ Heap Size ئه snapshot ای که در بخش Memory Usage گرفتیم ، با هم اون همه اختلاف دارن؟!

Process Memory میگه برنامه ام تا اون لحظه ، 98 مگابایت از حافظه را اشغال میکنه .
اما snapshot ئه دومی (که تقریبا در همون لحظه گرفته شد) ، ستونِ Heap Size اش میگه برنامه ام از 8.3 مگابایت استفاده میکنه .
این همه تفاوت ، برای چیه؟
قرار نبوده یکسان باشند، وقتی دو معیار متفاوت رو با هم مقایسه کنید مقدارشون هم میتونه متفاوت باشه.
و هم اینکه کتابخونه هایی که از حافظه های unmanaged هم استفاده میکنن (ما ، بصورت مستقیم ، از حافظه ی unmanaged در برنامه مون استفاده نمیکنیم . بلکه صرفا اون کتابخونه هایی که ازشون استفاده میکنیم ، اونها در دل خودشون از حافظه های unmanaged استفاده کنن) ، این نوع حافظه ها هم اطلاعات میزان استفاده از حافظه شون ، شامل در این snapshot ها میشه؟
در بحث حافظه پروسه چیزی به نام حافظه مدیریت شده و نشده نداریم، حافظه پروسه مربوط به سیستم عامل ئه که مستقل از NET. ئه. در سایر موارد مثل اون Heap Size، معیار حافظه برنامه در ماشین مجازی ئه، حافظه مدیریت شده است.
حالا اگه بیایم و ما خودمون مستقیما از حافظه ی unmanaged در کدمون استفاده کنیم ، چی؟ در این صورت هم اطلاعات این snapshot ها ، شامل اطلاعات میزان اشغال حافظه های unmanaged مون ، میشن؟
حافظه مدیریت نشده ای که به پروسه برنامه تخصیص می دهید طبعا بخشی از حافظه پروسه است، اما در آمار حافظه مدیریت شده برنامه مثل Heap Size نیست.
همچنین ، میشه بجای اینکه در snapshot ها ، دنبالِ همه ی اشیایی که از یک نوع استفاده میکنن ، بگردیم (که همه ی اشیا از یک نوعی که در کل برنامه مون وجود داره ، چقدر حافظه را اشغال کردن) ، بجاش ، صرفا دنبال یک متغییری بگردیم تا ببینیم که اون متغییرمون ، چه مقدار از حافظه را اشغال کرده؟ شدنی هست؟ اگه آره ، لینک منبعِ این قضیه یا توضیحی در این باره میدید؟
متغیر یک مفهوم داخل زبانی است، در اون snapshot مفهومش رو از دست داده.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
قرار نبوده یکسان باشند، وقتی دو معیار متفاوت رو با هم مقایسه کنید مقدارشون هم میتونه متفاوت باشه.

خیلی ممنون استاد .
در توضیحات Process Memory نوشته که
"حافظه ی شخصی اختصاص داده شده به پروسه . شامل heap ، stack و حافظه ی مجازی . بجز حافظه ای که با پروسه های دیگه ، به اشتراک گذاری شده هست" .


پس این که تقریبا مشخص هست .
اما Heap Size ، حداقل مگه بخش بزرگی از حافظه ای که به برنامه اختصاص داده میشه ، نیست؟
من آخر قضیه ی حافظه ی Heap را متوجه نشدم .
الان در شکل پست قبلی که ستون Heap Size داره ، دقیقا منظورش چیه؟
در واقع ، وقتی از حافظه ی Heap حرف میزنه ، از چه چیزی داره حرف میزنه؟
سئوال مهم ام اینه که چرا اون حافظه ی Heap ئه برنامه ، این همه اختلاف با Process Memory داره؟
یه کم توضیح بیشتر یا منبعی در این رابطه میدین؟


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

آها خیلی ممنون .

در سایر موارد مثل اون Heap Size، معیار حافظه برنامه در ماشین مجازی ئه، حافظه مدیریت شده است.

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

آره .
منتها در لینک زیر ، یه همچین چیزی نوشته :


The name of the columns depend on the debugging mode you choose in the project properties: .NET, native, or mixed (both .NET and native).

نمیدونم دقیقا منظورش چیه .
اگه منظورش اینه که نام ستون (ستون Managed Object) ، بستگی به debugging mode ای که در پنجره ی Properties ئه پروژه تون انتخاب میکنید (که یا .Net یا native یا هر دوشون میتونن باشن) ، داره ؛ من همچین گزینه ای در پنجره ی Properties ئه پروژه ام ندیدم .
صرفا در پنجره ی debug اش ، گزینه ای بنام "enable native code debugging" دیدم که با فعال کردنش ، فرقی در نام این ستون و همچنین در عنوان پنجره ی snapshot (که در قسمت بالای این پنجره ، عنوانش با Managed Memory شروع میشه) ، نکرد .

متغیر یک مفهوم داخل زبانی است، در اون snapshot مفهومش رو از دست داده.

انگار متوجه شدم یه جورایی .
وقتی در پنجره ی snapshot (عکس زیر در لینک زیر) :



memuse__snapshotdetails_managedheaptree.png


البته در نسخه ی ویژال استودیو 2019 این جوری هه که وقتی رویِ نامِ اون نوع دابل کلیک کنیم (مثل نوع SDKTemplate.MainPage در شکل بالا) ، به صفحه ی جدیدی منتقل میشه که تمام اشیاءِ اون نوع را لیست میکنه .

اما بدیش اینه که مثل تصویر بالا ، نام شی ها را بجای اینکه نام متغییرشون را بنویسه ، شی را بصورت عدد شونزده دهی مینویسه که نمیشه متوجه شد دقیقا کدوم شی هست (هر چند نام شیِ متغییر محلی را در کلوشه ، local variable مینویسه) .

تشکر استاد .
 

the_king

مدیرکل انجمن
اما Heap Size ، حداقل مگه بخش بزرگی از حافظه ای که به برنامه اختصاص داده میشه ، نیست؟
بر چه اساسی این رو میگید؟ هر برنامه ای مشخصات خودش رو داره و با نسبت های متفاوت میان حجم اجزاء اش.
من آخر قضیه ی حافظه ی Heap را متوجه نشدم .
الان در شکل پست قبلی که ستون Heap Size داره ، دقیقا منظورش چیه؟
منظورش حجم فعلی Heap در ماشین مجازی است که به اون برنامه اختصاص داده شده.
در واقع ، وقتی از حافظه ی Heap حرف میزنه ، از چه چیزی داره حرف میزنه؟
از حافظه Heap در ماشین مجازی NET. حرف میزنه، حافظه ای که GC مسئول مدیریتشه.
سئوال مهم ام اینه که چرا اون حافظه ی Heap ئه برنامه ، این همه اختلاف با Process Memory داره؟
چون دو تا مفهوم متفاوت هستند، مثل اینه که بگید چرا وزن شاسی پیکان با وزن خودرو پیکان این همه اختلاف داره.
یه کم توضیح بیشتر یا منبعی در این رابطه میدین؟
در مورد GC و Managed Heap جستجو کنید.
اگه منظورش اینه که نام ستون (ستون Managed Object) ، بستگی به debugging mode ای که در پنجره ی Properties ئه پروژه تون انتخاب میکنید (که یا .Net یا native یا هر دوشون میتونن باشن) ، داره ؛ من همچین گزینه ای در پنجره ی Properties ئه پروژه ام ندیدم .
صرفا در پنجره ی debug اش ، گزینه ای بنام "enable native code debugging" دیدم که با فعال کردنش ، فرقی در نام این ستون و همچنین در عنوان پنجره ی snapshot (که در قسمت بالای این پنجره ، عنوانش با Managed Memory شروع میشه) ، نکرد .
 

جدیدترین ارسال ها

بالا