سئوالات و مباحث WPF

SajjadKhati

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

بله.

طبعا اگر Binding ئه بر اساس PropertyChanged عمل می کنه همینطوره.

بله.

توضیح تون ایراد داره، شما Binding رو در رخداد CollectionChanged دخیل کرده اید، در حالی که قبلا عرض کردم که Binding نقشی در رخداد CollectionChanged نداره. اگر Binding ای هم وجود نداشت همین مساله برای رابطه ObsevableCollection و کنترل رخ میداد.
Binding قبلا شیء ObsevableCollection یا هر نوع داده دیگری که منبع بوده به کنترل تحویل داده، دیگه اینکه بعدا در هنگام تغییرات داخلی اون شیء چه رخداد هایی منجر به بروز رسانی در کنترل میشه نه ربطی به Binding داره و نه واسطه این ارتباط ئه و نه در بروز شون نقشی داره و نه از کار افتادن Binding تاثیری در این بروز رسانی بخاطر تغییر داخلی شیء میذاره.

درست نیست. ایراد به واسطه Converter شما است نه Binding دستی. فرض کنید که مقدار مشخصه X با Binding به مشخصه Y انتقال داده میشه، نتیجه اش اینه که شیء داخل X که مبداء هست در مقصد که Y ئه قابل دسترسی است، یک ارجاع ساده به شیء و طبعا Y به همون شیء اشاره داره که X. و اگر این شیء یک مجموعه باشه، اضافه کردن آیتم در X هیچ فرقی با اضافه کردن آیتم در Y نداره، هر دوشون به یک شیء اشاره دارند، اگر X چهار عضو داشته باشه، یعنی Y چهار عضو داره. محال ئه که در مجموعه داخل X تغییری رخ بده در حالی که Y (به همون شیء اشاره می کنه) بدون بروز رسانی مونده باشه.

سلامی مجدد
خیلی ممنون استاد .

آها ، پس وقتی Binding میکنیم ، هر دوی Binding Source Property و هم Binding Target Property ، از همون شی استفاده میکنن (مثل اینکه یک شی را توی یک متغییر بریزیم و بعد همون متغییر را توی متغییر دیگه ای بریزیم) .

بنابراین وقتی یه پروپرتیِ دستی (به عنوان Binding Target Property) که بسازیم و یه کالکشن را هم بهش Binding کنیم (و از Converter استفاده نکنیم) ، فقط کافیه که یکبار کالکشنِ سورس مون ، مقداردهی بشه ، همون کالکشن ، به عنوان کالکشن Target مون در نظر گرفته میشه . پس دیگه مهم هم نیست که دیگه با هر بار اضافه شدن آیتم به کالکشنِ سورس مون ، خبری به Binding یا Target داده بشه .
حالا به کالکشن Source مون هم که هر تغییری بدیم و اعضایی را حذف یا اضافه کنیم ، یعنی به همون کالکشنِ Target مون همون تغییرات را داده بودیم (چون شیِ کالکشنِ هر دو پروپرتی ، یکی هستن) .


حالا مشکل این پروژه ام اینه که برای این Binding ، از Converter استفاده کردم .
یعنی چون در اینجا ، میخوایم در هر بار حذف و اضافه شدنِ آیتم ها به کالکشنِ Source مون ، خبر دار بشیم تا برای کالکشنِ Target مون تبدیل انجام بدیم ، Binding ، هیچ روال و رویدادی را وقتی که عضوی به کالکشنِ Source مون اضافه بشه ، در نظر نمیگیره و بصورت اتوماتیک خبر دار نمیشه و چون در اینجا نیاز به Convert داریم و بنابراین دو شیِ کالکشنِ Source و Target از هم جدا هستن و بنابراین نیاز داریم هر بار وقتی که آیتم های کالکشن سورس مون تغییر میکنن ، با خبر بشیم ، پس به روش Binding معمولی ، دیگه جواب نمیده .


بلکه باید درون رویداد CollectionChanged ئه ObsevableCollection ئه Source مون برای با خبر شدن از تغییر در آیتم های کالکشن اش استفاده کنیم و با متدِ BindingExpression.UpdateTarget ، کالکشنِ Target مون را وادار به آپدیت شدن کنیم تا Binding بتونه Converter را فراخونی کنه .

درست میگم؟
تشکر استاد .
 

the_king

مدیرکل انجمن
سلامی مجدد
خیلی ممنون استاد .

آها ، پس وقتی Binding میکنیم ، هر دوی Binding Source Property و هم Binding Target Property ، از همون شی استفاده میکنن (مثل اینکه یک شی را توی یک متغییر بریزیم و بعد همون متغییر را توی متغییر دیگه ای بریزیم) .

بنابراین وقتی یه پروپرتیِ دستی (به عنوان Binding Target Property) که بسازیم و یه کالکشن را هم بهش Binding کنیم (و از Converter استفاده نکنیم) ، فقط کافیه که یکبار کالکشنِ سورس مون ، مقداردهی بشه ، همون کالکشن ، به عنوان کالکشن Target مون در نظر گرفته میشه . پس دیگه مهم هم نیست که دیگه با هر بار اضافه شدن آیتم به کالکشنِ سورس مون ، خبری به Binding یا Target داده بشه .
حالا به کالکشن Source مون هم که هر تغییری بدیم و اعضایی را حذف یا اضافه کنیم ، یعنی به همون کالکشنِ Target مون همون تغییرات را داده بودیم (چون شیِ کالکشنِ هر دو پروپرتی ، یکی هستن) .


حالا مشکل این پروژه ام اینه که برای این Binding ، از Converter استفاده کردم .
یعنی چون در اینجا ، میخوایم در هر بار حذف و اضافه شدنِ آیتم ها به کالکشنِ Source مون ، خبر دار بشیم تا برای کالکشنِ Target مون تبدیل انجام بدیم ، Binding ، هیچ روال و رویدادی را وقتی که عضوی به کالکشنِ Source مون اضافه بشه ، در نظر نمیگیره و بصورت اتوماتیک خبر دار نمیشه و چون در اینجا نیاز به Convert داریم و بنابراین دو شیِ کالکشنِ Source و Target از هم جدا هستن و بنابراین نیاز داریم هر بار وقتی که آیتم های کالکشن سورس مون تغییر میکنن ، با خبر بشیم ، پس به روش Binding معمولی ، دیگه جواب نمیده .


بلکه باید درون رویداد CollectionChanged ئه ObsevableCollection ئه Source مون برای با خبر شدن از تغییر در آیتم های کالکشن اش استفاده کنیم و با متدِ BindingExpression.UpdateTarget ، کالکشنِ Target مون را وادار به آپدیت شدن کنیم تا Binding بتونه Converter را فراخونی کنه .

درست میگم؟
نه الزاما، نیازتون برطرف کردن ایراد Converter بود، نه مجبور کردن Binding به Update کردن Target.
می توانستید از تبدیل به نوع دیگری استفاده نکنید، یا در همون Converter رخداد عامل تغییر رو به متد ای وصل کنید که شیء قبلا تبدیل شده رو به روز کنه (نه اینکه بخاطر هر تغییر شیء مجموعه جدیدی بسازید).
 

SajjadKhati

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

خیلی ممنون استاد .
آها . پس رویداد CollectionChanged ئه ObsevableCollection ئه Source (که همون پروپرتی Drives هست) را مستقیما به کلاس Converter متصل کنم و به اعضای DrivesForView اضافه کنم (نه اینکه هر بار شی جدید برای کالکشنِ DrivesForView در Converter درست کنم) .
بله ، این طوری از هر لحاظ بهتر میشه .
همین تغییرات را برای همین راهکاری که فرمودین در پروژه ی زیر اِعمال کردم .
تشکر استاد . :rose:
 

پیوست ها

  • SettingBinding.rar
    79.1 کیلوبایت · بازدیدها: 0

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد استاد .
استاد ، میخوام آموزش wpf (که قبلا یکی دو قسمت اش را ساخته بودم) را بسازم .
قبلا میخواستم که پروژه ی بکاپ گیری ام را اول تمام کنم و بعد ادامه ی آموزش را بسازم .

با این روندی که ساخت پروژه طول میکشه (به همراه مسائل شخصی ام که باعث میشه بیشتر طول بکشه) ، و همچنین قضیه ی درآمدم ، تصمیم گرفتم که روی کاغذ ، هر دوی آموزش و ساخت پروژه را با هم پیش ببرم (که ساخت آموزش ، الویت ام باشه) اما در عمل ، همیشه بیش از 70 یا 80 درصد و گاها همه ی اوقات را اونی که الویت ام میشه ، به خودش اختصاص میده . چون به سختی میتونم همزمان روی 2 کار تقسیم کنم .

قسمت اول اش آماده شده بود :


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

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

---------

بعد اینکه استاد من فروش این آموزش را با چند تا سایت مطرح کردم .
با بعضی ها هم بعدش آشنا شدم و هنوز مطرح نکردم .
توی اونهایی که مطرح کردم ، فعلا یکی شون قبول کردن ؛ بعضی های دیگه قبول نکردن (مثل فرادرس و یکی دو تای دیگه) ، بعضی ها را بخاطر شرایط ، من قبول نکردم (که معمولا مالی بودن و آموزش را یکباره میخریدن اون هم با قیمت بسیار کم در صورتی که ساخت این آموزش که بیش از 100 قسمتِ یک ساعته میشه ، بصورت متوسط ، یک سال یا ماه ها زمان میبره و یا بعضی شرایط دیگه داشتن که بالاخره مورد قبولم نبود) .

بعد یادم اومد که با سایت شما هم برای قرار دادن آموزش صحبت کنم . نمیدونم که سایت مجید آنلاین ، برای شماست یا کس دیگه ای یا کلا آموزش wpf را توش قبول میکنید که بذارید یا نه ، یا اگه آره ، شرایط خاصی دارید یا نه؟

همچنین با سایت های دیگه مثل یاس دانلود و سبز لیرن و برنامه نویس و اینها احتمالا صحبت میکنم .
بستر فروش آموزش اگه آماده تر میبود یا اگه سایتی میداشتم ، خیلی خوب میشد .

ویژگی های WPF نسبت به Windows Form :


1) استفاده از XML در طراحی رابط کاربری :

- باعث جدا کردن طراحی رابط کاربری از منطق تجاری میشه .

فایده اش اینه که طراح رابط کاربری با برنامه نویسی منطق تجاری میتونه جدا از هم بصورت همزمان انجام بشه .

استاد ، این جمله که "wpf اجازه میده که برنامه نویس و طراح ، کارشون را مجزا و همزمان انجام بدن" ، را یکی از آموزش دهنده ها در یکی از آموزش های udemy بصورت انگلیسی گفت . هر چند علاوه بر این ، ممکنه در سایتی هم دیده باشم .

به نظرتون این جمله ، دقیق هست؟
اگه دقیق هست ، به نظرتون ، به چه چیز و به چه قابلیت از wpf اشاره میکنه که باعث این جداسازی و همزمانیِ نوشتنِ رابط کاربری و منطق تجاری میشه؟

آیا منظورش صرف اینکه در wpf ، رابط کاربری را در xaml مینویسیم و منطق تجاری را در سی شارپ مینویسیم ، هست؟

اگه منظورش این باشه ، شاید چندان خوب یا دقیق به نظر نرسه چون بالاخره در هر دوی wpf و winform میشه ظاهر را بدون نوشتنِ مستقیمِ کد (در winform ، کد سی شارپ و در wpf ، کد xaml) و صرفا با درگ و دراپ کردن کنترل ها ، ساخت .

یا اینکه منظورش وقتی که معماری mvvm را پیاده سازی میکنیم ، هست؟ که با این معماری ، توسط viewmodel ، لایه های view و model را از هم جدا میکنیم؟

یا به نظرتون ، به هیچ کدوم از اینها مربوط نیست و فرضا آیا برای استفاده از Binding هست؟
فرضا برای اینه که در Binding ، پروپرتیِ Path اش ، یه مسیر (ای از پروپرتی ، فرضا به عنوان رشته) دریافت میکنه و حتی با عدم وجودِ اون مسیر ، همچنان اون برنامه ، حداقل اجرا (run) میشه ، هر چند ممکنه اگه اون مسیر (ی که در Binding مشخص شد) وجود نداشته باشه ، زمان اجرا ، Binding ای انجام نشه (هر چند در معماری mvvm ، بیشترین استفاده از Binding میشه) ؟

کلا میخواستم دقیق تر بدونم که همچون جمله ای که گفتن ، دقیقا برای کدوم ویژگی از wpf گفتن؟
اما هر چند ممکنه حتی درست باشه ، اما به نظر میاد که حتی به هیچ کدوم از این 3 گزینه ، خیلی زیاد نمیاد و شاید دقیق نباشه .
به نظرتون اون جمله ، دقیق هست؟

------------

بعد اینکه در سایت زیر ، برای ویژگی جداسازی mvvm ، همچین چیزی گفت که به نظرم دقیق هست :


  • Separation of concerns – Typically, there is a connection between the user interface and application logic, resulting in change-resistant, brittle code. MVVM cleanly separates the user interface from the application logic. Divorcing one from the other improves application maintenance. It also makes application evolution easier, thereby reducing the risk of technological obsolescence.

چون در این جمله که دقت کنید ، فقط از صفات تفصیلی (نسبت برتری با غیر از mvvm) برای mvvm اشاره کرد .
در این جمله گفت که عیب استفاده نکردن از mvvm ، کدهای مقاوم در برابر تغییرات (و همچنین کدهای شکننده که منظورش از شکننده را دقیق متوجه نشدم) هست (که احتمالا منظورش از تغییرات ، تغییراتِ چه کدهای لایه ی view یا model یا جایگزینی شون در آینده هست) .

یعنی نگفت که در mvvm ، صد درصد کدها ، تغییر پذیرند و در غیر mvvm ، صد درصد کدها ، تغییر ناپذیرند . بلکه گفت که غیر از mvvm ، مقاومت (بیشتر) دارن .

همچنین گفت که mvvm ، باعث بهبود نگهداری کد میشه (باز هم نگفت که کدهای غیر از mvvm را نمیشه نگه داری کرد) .
باز هم همچنین گفت که کدهای mvvm ، تکامل راحت تر دارن (نگفت کدهای غیر mvvm ، کلا تکامل ناپذیرند) .

یعنی در کل گفت کدهای mvvm ، بهتر هست و اینها (از صفت تفصیلی استفاده کرد) . یعنی نیومد بگه که چیزی که در mvvm بشه ، در غیر از mvvm نمیشه .

اما در اون جمله ای که گفتم اون طرف در آموزش udemy برای wpf گفت (که نمیدونم برای چه ویژگی ای از wpf گفت . هر چند احتمال میدم که برای معماری mvvm اش گفته باشه) ، از این صفت استفاده نکرد . صرفا گفت که در wpf میشه کار را همزمان و مجزا انجام داد (که به این معناست که در winform نمیشه . چون قبل اش معایب winform را گفته بود و میخواست ویژگی های wpf و winform را از هم جدا کنه) .

ببخشید زیاد شد .
تشکر استاد :rose:
 

the_king

مدیرکل انجمن
بعد یادم اومد که با سایت شما هم برای قرار دادن آموزش صحبت کنم . نمیدونم که سایت مجید آنلاین ، برای شماست یا کس دیگه ای یا کلا آموزش wpf را توش قبول میکنید که بذارید یا نه ، یا اگه آره ، شرایط خاصی دارید یا نه؟
یک زمانی مجید آنلاین فروشگاه داشت، اما من هیچوقت در این موارد مسئولیتی نداشتم. من فقط انجمن رو مدیریت می کردم.
الانم که فروشگاه تعطیل ئه. اگر بخواهید می توانید به مدیریت پیام بدهید اما من امکانات یا اختیاری در این مورد ندارم.
استاد ، این جمله که "wpf اجازه میده که برنامه نویس و طراح ، کارشون را مجزا و همزمان انجام بدن" ، را یکی از آموزش دهنده ها در یکی از آموزش های udemy بصورت انگلیسی گفت . هر چند علاوه بر این ، ممکنه در سایتی هم دیده باشم .

به نظرتون این جمله ، دقیق هست؟
بله.
اگه دقیق هست ، به نظرتون ، به چه چیز و به چه قابلیت از wpf اشاره میکنه که باعث این جداسازی و همزمانیِ نوشتنِ رابط کاربری و منطق تجاری میشه؟
اینکه ظاهر واسط کاربری میتونه بدون هیچگونه کد برنامه نویسی در XAML مشخص بشه. قبلا در این مورد صحبت کردیم.
آیا منظورش صرف اینکه در wpf ، رابط کاربری را در xaml مینویسیم و منطق تجاری را در سی شارپ مینویسیم ، هست؟
بله.
اگه منظورش این باشه ، شاید چندان خوب یا دقیق به نظر نرسه چون بالاخره در هر دوی wpf و winform میشه ظاهر را بدون نوشتنِ مستقیمِ کد (در winform ، کد سی شارپ و در wpf ، کد xaml) و صرفا با درگ و دراپ کردن کنترل ها ، ساخت .
شما چه بصورت خودکار و چه بصورت دستی نهایتا دارید کد سی شارپ در Designer تولید می کنید، مستقل از کد سی شارپ برنامه که نیست.
یا اینکه منظورش وقتی که معماری mvvm را پیاده سازی میکنیم ، هست؟ که با این معماری ، توسط viewmodel ، لایه های view و model را از هم جدا میکنیم؟
نه الزاما قواعد MVVM لازم نیست رعایت بشه.
یا به نظرتون ، به هیچ کدوم از اینها مربوط نیست و فرضا آیا برای استفاده از Binding هست؟
Binding در WinForms هم هست. وجودش هم نه ضروری است و نه کافی. Binding نبود هم خود برنامه نویس می توانست یک روالی رو جایگزینش کنه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد استاد .
خیلی ممنون از جواب تون .

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

============

استاد ، به لینک زیر ، و جواب اولی (پست دومی) نگاه کنید :


درباره ی اینه که در MVVM ، آیا بهتره که View را به ViewModel مون ، Binding کنیم یا به Model مون Binding کنیم .

طرف میگه (تا جایی که متوجه شدم و نقل به مضمون) ، هر چند اغلب برنامه نویس ها ، View را به Model شون Binding میکنن ، اما اون طرف در این کار 2 اشکال اساسی میبینه .

اولیش را دقیق متوجه نشدم . اما اندکی که متوجه شدم انگار میگه اگه View ، پروپرتی های Model را آپدیت کنه ، این تغییرات ، بخوبی روی دیتابیس برای صفحات (و View هایی که) دکمه ی save دارن ، انجام نمیشه .

دومی را میگه که چون اغلب در Model ، اینترفیس INotifyPropertyChanged را پیاده سازی نمیکنن ، پس زمان آپدیت و تغییرات در صفحه ، مناسب binding target نیست .

---------

اون دومیش را قبلا به این نتیجه رسیدیم که در یه پستی هم که قبلا گفتم ، اینترفیس INotifyPropertyChanged را پیاده سازی کنیم و من هم برای Model و هم ViewModel ام این کار را میکنم .
پس ، این مشکل دومی که میگیره ، به کارمون نمیاد و مشکلی نیست .

مشکل اولی را دقیقا چی میگه و نظرتون درباره ی اون مشکلی که میگه چیه؟
تشکر
 

the_king

مدیرکل انجمن
سلامی مجدد استاد .
خیلی ممنون از جواب تون .

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

============

استاد ، به لینک زیر ، و جواب اولی (پست دومی) نگاه کنید :


درباره ی اینه که در MVVM ، آیا بهتره که View را به ViewModel مون ، Binding کنیم یا به Model مون Binding کنیم .

طرف میگه (تا جایی که متوجه شدم و نقل به مضمون) ، هر چند اغلب برنامه نویس ها ، View را به Model شون Binding میکنن ، اما اون طرف در این کار 2 اشکال اساسی میبینه .

اولیش را دقیق متوجه نشدم . اما اندکی که متوجه شدم انگار میگه اگه View ، پروپرتی های Model را آپدیت کنه ، این تغییرات ، بخوبی روی دیتابیس برای صفحات (و View هایی که) دکمه ی save دارن ، انجام نمیشه .

دومی را میگه که چون اغلب در Model ، اینترفیس INotifyPropertyChanged را پیاده سازی نمیکنن ، پس زمان آپدیت و تغییرات در صفحه ، مناسب binding target نیست .

---------

اون دومیش را قبلا به این نتیجه رسیدیم که در یه پستی هم که قبلا گفتم ، اینترفیس INotifyPropertyChanged را پیاده سازی کنیم و من هم برای Model و هم ViewModel ام این کار را میکنم .
پس ، این مشکل دومی که میگیره ، به کارمون نمیاد و مشکلی نیست .

مشکل اولی را دقیقا چی میگه و نظرتون درباره ی اون مشکلی که میگه چیه؟
تشکر
فرقی نمی کنه که به چی Bind می کنید. مهم اینه که بدونید رخداد تغییر یافتن مقدار مشخصه رو نباید به رویدادی مثل ذخیره سازی داده وصل کنید.
اصل مساله در خود Binding ئه. Binding بخوبی شرایطی که باید ثبت داده های واسط کاربری رو در Model طی کنه پوشش نمیده. مشکل اول حاصل منطق اشتباه خود برنامه نویس ئه، فرض رو بر این گرفته که اگر مشخصه x در واسط Model تغییر کرد پس باید بلافاصله Model اقدام به ثبت مقدار جدید x کنه، بدون هیچ شرط و منطق تکمیلی. همچین منطقی در اغلب واسط های کاربری نامناسب میشه.
اینکه در View مقدار ظاهری چیزی تغییر کرد و بلافاصله Binding مقدار مشخصه ای رو در Model تغییر داد، به این معنی نیست که درخواست ثبت اش هم در Model وجود داشته، این فقط یک رفتار عادی Binding ئه، الزاما جزئی از روال Save کاربر نیست.
باید در اون سمت دریافت کننده واسط مناسبی نوشته باشید که در زمان مناسب برای ذخیره سازی یا واکشی داده بکار بره، فقط تغییر مقدار مشخصه به این معنی نیست که پس باید الان Save بشه.
 

SajjadKhati

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

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

منظورتون از ثبت مقدار جدید x (در صورت تغییر مقدار پروپرتی) اینه که توسط متد DependencyObject.SetValue (یا متد SetCurrentValue) ، مقدار فیلدِ استاتیکِ dependency property اش را تغییر بده؟

اینکه در View مقدار ظاهری چیزی تغییر کرد و بلافاصله Binding مقدار مشخصه ای رو در Model تغییر داد، به این معنی نیست که درخواست ثبت اش هم در Model وجود داشته، این فقط یک رفتار عادی Binding ئه، الزاما جزئی از روال Save کاربر نیست.
باید در اون سمت دریافت کننده واسط مناسبی نوشته باشید که در زمان مناسب برای ذخیره سازی یا واکشی داده بکار بره، فقط تغییر مقدار مشخصه به این معنی نیست که پس باید الان Save بشه.

منظورتون از درخواست ثبت را متوجه نشدم دقیقا چیه؟

اما استاد ، به نظرم اصلا طرف یه چیز درستی را فرض نمیکنه و نتیجه اش هم چندان درست نیست .
یعنی فرض کنید که در view ، یه ListBox ای از نام دانش آموزان دارید و طبعا دو دکمه ی حذف و اضافه کردن در کنار این لیست باکس دارید . محتویات این ListBox را هم به پروپرتی ای در کلاسی (فرضا کلاسی بنام Student) در Model تون ، Binding میکنید .
میخواید هم هر چیزی به این ListBox اضافه شد ، علاوه بر اینکه به اون پروپرتی ای که در Model مون Binding شده بود ، در دیتابیس هم ذخیره بشه .

در این صورت ، اول اینکه درستش اینه که کلاس دیتابیس مون و متدهای ذخیره سازی توی دیتابیس ، جدای از کلاسی باشن که عملیات محاسبات مربوط به View را در Model ارائه میکنن (فرضا در کلاسی بنام Database در لایه ی Model) .
دوم اینکه اصلا روال دیتابیس ، در متد معمولا انجام میشه . پروپرتی نیست که بخواد مستقیما به ListBox مون Binding بشه .

نهایتا من این طور در نظر میگیرم که وقتی محتوای ListBox تغییر کرد :
- یا به روشی غیر از Binding ، متد مربوط به ذخیره سازی در کلاس مربوط به دیتابیس را فراخونی کنیم . یعنی به روش عادی ، متدی در ViewModel و از ViewModel هم متد مربوط به کلاس دیتابیس (کلاسی که نامش Database بود) در لایه ی Model را فراخونی کنیم .

- یا اینکه وقتی محتویات ListBox به پروپرتی مورد نظر در کلاس Student مون Binding شده هستند ، از validate و اعتبارسنجی یا از convert در Binding (یا شبیه این روال ها در Binding) که در لایه ی ViewModel این اعتبار سنجی یا تبدیل داده انجام میگیره ، استفاده کنیم تا اطلاعاتش را به متد مورد نظر در کلاس Database بفرستیم و اون متد را فراخونی کنیم .

درست میگم؟

================================================


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


به هر حال ، عکس زیر را درباره ی توضیح کلی mvvm آماده کردم . مشکلی که نداره؟


MVVM Visio.jpg


قسمت دوم ، صرفا کلیات mvvm در 5 دقیقه یا کمتر هست .
عکس بالا هم به عنوان همین کلیات هست که میخوام توضیح بدم .
برای شما ، این عکس را توضیح بدم (تا بررسی کنید که درست هست یا نه) یا اینکه توضیح نمیخواد و واضح هست؟
چون فکر میکنم واضح هست ، فعلا براتون توضیح نمیدم (اگه خواستید ، بگید توضیح هم بدم) چون علاوه بر عکس ، بخش عمده و بسیاری از چه mvvm (و چه wpf و سی شارپ و کلا برنامه نویسی) را از خودتون گرفتم ، حس میکنم در جریانِ اطلاعاتی که دارم باشید (واسه همین توضیح ندادم) .

تشکر استاد :rose:
 

the_king

مدیرکل انجمن
سلامی مجدد
خیلی ممنون استاد . :rose:

منظورتون از ثبت مقدار جدید x (در صورت تغییر مقدار پروپرتی) اینه که توسط متد DependencyObject.SetValue (یا متد SetCurrentValue) ، مقدار فیلدِ استاتیکِ dependency property اش را تغییر بده؟
مقدار فیلد استاتیک؟ شما دو تا شیء از نوع کلاس A دارید که داخلش dependency property داره، اگر این مقدار فیلد استاتیک باشه که داخل این کلاس A تغییر کنه، نتیجه اش باید این باشه که این دو تا شیء نتوانند مقدار متفاوتی برای اون مشخصه داشته باشند، چون فیلد استاتیک تعلق به کلاس داره، نه شیء. در حالی که اینطور نیست و هر شیء میتونه مقدار متفاوتی برای اون مشخصه داشته باشه. پس فیلدی که مقدارش تغییر می کنه نمی تونه استاتیک باشه.
منظورتون از درخواست ثبت را متوجه نشدم دقیقا چیه؟
فرضا روی فرم یک دکمه Save است. کاربر وقتی در فرم دکمه Save رو فشار میده هیچ دخالتی در روالی که با این کلیک اجرا میشه نداره.
View هم که خودش دخالتی در وظایف Model نداره و برای ذخیره سازی تصمیم نمی گیره، درخواست ثبت نهایتا ارسال میشه به Model.
این Model ئه که باید تصمیم بگیره به این درخواست چه واکنشی داشته باشه. میتونه درخواست رو رد کنه.

اما استاد ، به نظرم اصلا طرف یه چیز درستی را فرض نمیکنه و نتیجه اش هم چندان درست نیست .
یعنی فرض کنید که در view ، یه ListBox ای از نام دانش آموزان دارید و طبعا دو دکمه ی حذف و اضافه کردن در کنار این لیست باکس دارید . محتویات این ListBox را هم به پروپرتی ای در کلاسی (فرضا کلاسی بنام Student) در Model تون ، Binding میکنید .
میخواید هم هر چیزی به این ListBox اضافه شد ، علاوه بر اینکه به اون پروپرتی ای که در Model مون Binding شده بود ، در دیتابیس هم ذخیره بشه .
این "میخواهید" رو کی داره میگه؟ طراح View. طراحی View ارتباطی با آنچه در Model میگذره نداره، طراح View برای طراح Model تکلیف تعیین نمی کنه. اینکه در View فلان مدل رو می پسندید معنی اش این نیست که Model باید به فلان شیوه تغییر کنه. ViewModel رو طوری طراحی می کنید که آنچه در View لازم دارید توسط Model تامین بشه، نه اینکه Model تغییر کنه.
در این صورت ، اول اینکه درستش اینه که کلاس دیتابیس مون و متدهای ذخیره سازی توی دیتابیس ، جدای از کلاسی باشن که عملیات محاسبات مربوط به View را در Model ارائه میکنن (فرضا در کلاسی بنام Database در لایه ی Model) .
دوم اینکه اصلا روال دیتابیس ، در متد معمولا انجام میشه . پروپرتی نیست که بخواد مستقیما به ListBox مون Binding بشه .
"عملیات محاسبات مربوط به View را در Model ارائه میکنن" در MVVM چه معنایی داره؟ وقتی Model هیچ ارتباطی با View نداره چطور میتونه عملیات محاسباتی مرتبط با View در Model باشه؟
"روال دیتابیس معمولا در متد انجام میشه" بر اساس کدوم قاعده است؟ این قاعده رو کی تعیین کرده؟
نهایتا من این طور در نظر میگیرم که وقتی محتوای ListBox تغییر کرد :
- یا به روشی غیر از Binding ، متد مربوط به ذخیره سازی در کلاس مربوط به دیتابیس را فراخونی کنیم . یعنی به روش عادی ، متدی در ViewModel و از ViewModel هم متد مربوط به کلاس دیتابیس (کلاسی که نامش Database بود) در لایه ی Model را فراخونی کنیم .

- یا اینکه وقتی محتویات ListBox به پروپرتی مورد نظر در کلاس Student مون Binding شده هستند ، از validate و اعتبارسنجی یا از convert در Binding (یا شبیه این روال ها در Binding) که در لایه ی ViewModel این اعتبار سنجی یا تبدیل داده انجام میگیره ، استفاده کنیم تا اطلاعاتش را به متد مورد نظر در کلاس Database بفرستیم و اون متد را فراخونی کنیم .

درست میگم؟
شما یک واسط کاربری خاص برای View در نظر گرفته اید، بعد بر اساس اش دارید واسط Model ای رو طراحی می کنید که به ساده ترین شکلی که در ذهن تون هست با اون ViewModel تعامل داشته باشه و بعد میخواهید این حالت خاص رو تعمیم بدهید به یک قاعده کلی برای معماری MVVM. که طبعا هر نتیجه ای بگیرید اشتباه ئه.
اینکه در ListBox یک آیتم Student جدید اضافه شد معنی اش این نیست که باید الان و بلافاصله در Model هم ذخیره بشه.
به هر حال ، عکس زیر را درباره ی توضیح کلی mvvm آماده کردم . مشکلی که نداره؟
می توانید از Binding بین ViewModel و Model مثالی بزنید؟ جایی دیدید که Binding از محدوده بین View و ViewModel فراتر بره؟
خطوط Binding و Binding Notification رو طوری یکسره بین View و Model رسم نکنید که انگار بین View و Model لاینقطع ادامه داره.
 

SajjadKhati

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

سلامی مجدد
خیلی ممنون استاد :rose:

شناسه ی DependencyProperty که میدونیم فیلد استاتیک هست و پروتوتایپ اش هم بصورت زیر هست :

C#:
public static readonly DependencyProperty NamedProperty;

و صرفا با متدهای DependencyObject.SetValue یا SetCurrentValue میشه توشون نوشت و با GetValue میشه خوندش .
منتها من چمیدونم این متدها یا شیِ DependencyProperty ، توشون چه اعضا یا روشی بکار بردن و چجوری مقدارش را میخونن .

بررسی هم نکردم که بدونم چجوری کار میکنه . فرضا ممکنه وقتی متد GetValue را فراخونی میکنیم ، مقدارش را از توی آرایه یا فیلد دیگه ای برای فیلد NamedProperty (که مربوط به پروپرتی خاصی ثبت کردیم) ، بخونه . بررسی نکردم که از چه روشی استفاده میکنه . نمیدونم .

به هر حال ظاهر کار اینه که ما با متد GetValue و SetValue توی اون فیلد استاتیک مینویسیم و میخونیم اما توی این متدها چه اتفاقی میافته که با این متد استاتیک ، بصورت شی گرا رفتار میشه را نمیدونم .

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

شما میدونید که رفتار این متدها با این فیلد استاتیک چجوری هست که نهایتا جوری میشه که ما در خروجی ، رفتارش را در غالب فراخونی اون متدها ، بصورت شی گرا میبینیم؟

نهایتا نگفتید منظورتون از ثبت مقدار جدید x ، چیه؟ (سئوالی که در پست قبل پرسیدم) .

فرضا روی فرم یک دکمه Save است. کاربر وقتی در فرم دکمه Save رو فشار میده هیچ دخالتی در روالی که با این کلیک اجرا میشه نداره.
View هم که خودش دخالتی در وظایف Model نداره و برای ذخیره سازی تصمیم نمی گیره، درخواست ثبت نهایتا ارسال میشه به Model.
این Model ئه که باید تصمیم بگیره به این درخواست چه واکنشی داشته باشه. میتونه درخواست رو رد کنه.

آها .
خیلی ممنون استاد .

این "میخواهید" رو کی داره میگه؟ طراح View. طراحی View ارتباطی با آنچه در Model میگذره نداره، طراح View برای طراح Model تکلیف تعیین نمی کنه. اینکه در View فلان مدل رو می پسندید معنی اش این نیست که Model باید به فلان شیوه تغییر کنه. ViewModel رو طوری طراحی می کنید که آنچه در View لازم دارید توسط Model تامین بشه، نه اینکه Model تغییر کنه.

نه . ربطی به تغییر نداره .
منظورم اینه که بالاخره یه متدی یا عضوی در لایه ی Model باید باشه تا داده های مربوط به دیتابیس را ذخیره کنه دیگه . بحث تغییر نیست . حالا میگم اون متد ، متدی در کلاسی بنام Database که این کلاس متعلق به لایه ی Model هست ، در نظر بگیرید .

علاوه بر این ، یه چهارچوب کلی ای باید باشه که View ، در راستای Model کنه . فرضا نمیشه Model ای برای فتوشاپ نوشته بشه اما View ای برای explorer.exe طراحی بشه . خود مجموعه ی دستندرکارهای اون برنامه ، تصمیم میگیرن که به هر دو قالب بدن (یا تغییر بدن) .

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

"عملیات محاسبات مربوط به View را در Model ارائه میکنن" در MVVM چه معنایی داره؟

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

یعنی فرضا کلاس Student (یا شاید هم کلاس مربوط به ViewModel) ، اطلاعات مورد نیازی که لازمه را برای متد یا عضو مورد نظر در کلاس Database ، ارسال و فراخونی کنه . و اون متد ، کار ذخیره سازی را در دیتابیس انجام بده .

وقتی Model هیچ ارتباطی با View نداره چطور میتونه عملیات محاسباتی مرتبط با View در Model باشه؟

منظورم این نیست که Model ، ارتباطی با View داشته باشه .
توضیح بیشتر بدم ، بحث کش دار میشه . :) در حالی که منظور خودم را میدونم .

"روال دیتابیس معمولا در متد انجام میشه" بر اساس کدوم قاعده است؟ این قاعده رو کی تعیین کرده؟

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

شما یک واسط کاربری خاص برای View در نظر گرفته اید، بعد بر اساس اش دارید واسط Model ای رو طراحی می کنید که به ساده ترین شکلی که در ذهن تون هست با اون ViewModel تعامل داشته باشه و بعد میخواهید این حالت خاص رو تعمیم بدهید به یک قاعده کلی برای معماری MVVM. که طبعا هر نتیجه ای بگیرید اشتباه ئه.
اینکه در ListBox یک آیتم Student جدید اضافه شد معنی اش این نیست که باید الان و بلافاصله در Model هم ذخیره بشه.

موضوع مسئله ام این نبود .

می توانید از Binding بین ViewModel و Model مثالی بزنید؟ جایی دیدید که Binding از محدوده بین View و ViewModel فراتر بره؟
خطوط Binding و Binding Notification رو طوری یکسره بین View و Model رسم نکنید که انگار بین View و Model لاینقطع ادامه داره.

این جوری تغییر دادم ، خوبه؟ البته منظورم در شکل بالا هم همین شکل زیر بود . ولی به قول شما اگه جدا کنم ، منظورم واضح تر میشه :


MVVM 2 - Complex.jpg

=====================

استاد ، درون لایه ی Model در معماری 3 لایه (که همون منطق تجاری هست) (منظورم در معماری mvvm نیست) ، هیچ اثری از View یا کنترل های View درون متدها و کلا اعضای Model نیست دیگه . درسته؟

یعنی در معماری 3 لایه هم ، درون ورودی های متد های Model مون ، این طور نیست که شی ای از Control (یا کلا اطلاعاتی مربوط به View که به user interface مربوط بشه) داشته باشیم (برای اینکه Model ، بخواد داده ای را از لایه ی View جدا و دریافت کنیم) . درسته؟

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

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

درسته؟
یعنی این قضیه ربطی به معماری mvvm و حتی شاید ربطی به معماری 3 نداره . درسته؟

اگه درستن ، پس در این صورت ، حتی در معماری 3 لایه هم ، لایه ی Model یا منطق تجاری اش ، از لحاظ به روزرسانی در نسخه های بعدیِ این لایه ، یا از لحاظ انتقال کدهای این لایه و همچنین نگه داریش ، هیچ فرقی با این لایه در معماری mvvm نمیکنه . درسته؟

پس با این حال ، فرق معماری mvvm با 3 لایه ، فقط در دو لایه ی View با ViewModel هست که اندکی انتقال و نگه داری و به روزرسانی لایه ی View ، نسبت به همین لایه درون معماری 3 لایه ، بهتر میشه .
درست میگم؟

تشکر :rose:
 

the_king

مدیرکل انجمن
سلامی مجدد
خیلی ممنون استاد :rose:

شناسه ی DependencyProperty که میدونیم فیلد استاتیک هست و پروتوتایپ اش هم بصورت زیر هست :

C#:
public static readonly DependencyProperty NamedProperty;

و صرفا با متدهای DependencyObject.SetValue یا SetCurrentValue میشه توشون نوشت و با GetValue میشه خوندش .
منتها من چمیدونم این متدها یا شیِ DependencyProperty ، توشون چه اعضا یا روشی بکار بردن و چجوری مقدارش را میخونن .

بررسی هم نکردم که بدونم چجوری کار میکنه . فرضا ممکنه وقتی متد GetValue را فراخونی میکنیم ، مقدارش را از توی آرایه یا فیلد دیگه ای برای فیلد NamedProperty (که مربوط به پروپرتی خاصی ثبت کردیم) ، بخونه . بررسی نکردم که از چه روشی استفاده میکنه . نمیدونم .

به هر حال ظاهر کار اینه که ما با متد GetValue و SetValue توی اون فیلد استاتیک مینویسیم و میخونیم اما توی این متدها چه اتفاقی میافته که با این متد استاتیک ، بصورت شی گرا رفتار میشه را نمیدونم .
ظاهر قضیه اینه که در فیلد static readonly مقدار خونده و نوشته میشه؟ لااقل یک چیزی از ظاهر نتیجه بگیرید که با قواعد زبان #C منافاتی نداشته باشه.
ولی بالاخره بصورت مستقیم که خودمون اطلاعات این فیلد را فراخونی نمیکنیم (که استاتیک بودن یا نبودنش برای اینکه بصورت شی گرا رفتار کنه یا نکنه ، مهم باشه) . بصورت غیر مستقیم و توسط اون متدها استفاده میکنیم (که توی دل این متدها ، کاری میکنن که نهایتا در خروجی ، رفتار شبیه شی گرا از این فیلد میبینیم . نه اینکه این فیلد استاتیک ، شی گرا باشه) . اون فیلد هم استاتیک هست دیگه .
شما از طرف میگید من بررسی نکردم که در اون روال ها چی میگذره و از طرف دیگه برای مساله ای که بررسی نکرده اید نتیجه گیری ای می کنید که با قواعد زبان #C منافات داره.
شما میدونید که رفتار این متدها با این فیلد استاتیک چجوری هست که نهایتا جوری میشه که ما در خروجی ، رفتارش را در غالب فراخونی اون متدها ، بصورت شی گرا میبینیم؟
شیء گرایی منافاتی با static بودن نداره. static object x همونقدر شیء ئه که object x شیء ئه. شیء گرایی همیشه سر جاش هست، جایی نقض نمیشه. اگر به متد های DependencyObject توجه کنید می بینید که GetValue و SetCurrentValue و ... متد های static ای نیستند، عملکرد شون به instance اجرا کننده وابستگی داره.
نهایتا نگفتید منظورتون از ثبت مقدار جدید x ، چیه؟ (سئوالی که در پست قبل پرسیدم) .
فرضا در Model یک مشخصه Student هست یا یک مشخصه StudentName هست، که جزئی از واسط Model برای ارتباط با ViewModel ئه.
و ثبت مقدار جدید در هر کدوم از این مشخصه ها صرفا بخشی از یک فرایند ئه، نه کل فرایند، بخشی از فرایند ذخیره سازی یک Student جدید، بخشی از فرایند ویرایش یک Student و ... . حالا اگر ViewModel در یکی از ایندو مشخصه مقدار جدیدی ثبت کرد، آیا باید Model بلافاصله اقدام به ذخیره سازی اون مقادیر در پایگاه داده بکنه؟ الزاما خیر. حتما نباید همچین کاری بکنه، الزامی نیست. یعنی اگر Binding ای با هر تغییری در View بلافاصله مقدار مشخصه ای رو در Model تغییر داد، الزاما نباید Model با ذخیره کردن مقدار جدید واکنش نشون بده. که اگر اینکار رو بکنه به مشابه اون نقل قول "That doesn't work well for edit-screens that have a Save/Cancel button"، این واسطی میشه که برای دکمه های Save/Cancel مناسب نیست.
این جوری تغییر دادم ، خوبه؟ البته منظورم در شکل بالا هم همین شکل زیر بود . ولی به قول شما اگه جدا کنم ، منظورم واضح تر میشه :
پاسخ سوال ام رو ندادید. شما الان یک Binding دارید که از View مستقیم رفته به سمت Model. یا Notification ای هم دارید از Model مستقیم به View رسیده. مثال این دو ارتباط چیه که با معماری MVVM هم تناقض نداشته باشه؟

استاد ، درون لایه ی Model در معماری 3 لایه (که همون منطق تجاری هست) (منظورم در معماری mvvm نیست) ، هیچ اثری از View یا کنترل های View درون متدها و کلا اعضای Model نیست دیگه . درسته؟
نه. نیست. فقط داده است و مدیریت داده. داده ای که ساخته میشه، داده ای که واکشی میشه، ذخیره میشه، و ... هیچ چیزی که به واسط کاربری و تعامل با کاربر مرتبط باشه نداره.
یعنی در معماری 3 لایه هم ، درون ورودی های متد های Model مون ، این طور نیست که شی ای از Control (یا کلا اطلاعاتی مربوط به View که به user interface مربوط بشه) داشته باشیم (برای اینکه Model ، بخواد داده ای را از لایه ی View جدا و دریافت کنیم) . درسته؟
استخراج داده از Control یا درج داده در Control رو یا باید خود View انجام بده. و تحت هیچ شرایطی نباید از محدوده ViewModel View خارج بشه و وارد ناحیه Model بشه.
یعنی در معماری 3 لایه هم ، برای گرفتن داده ای از View ، صرفا داده ی مورد نظرش (مثل رشته یا عدد و اینها) را دریافت میکنه و مسئول جدا سازیِ داده ی مورد نظر از کنترل خاص برای ارسال به Model ، خود View مسئولش هست . درسته؟
بله. مسئولیت اش با View ئه.
حتی ربطی به معماری 3 لایه هم نداره و حتی بدون این معماری هم همینطوره . درسته؟
بله. هر لایه مسئولیت خودش رو داره.
اساسا لایه ی جلوتر ، نباید (یا لازم نیست) که هیچ اطلاعاتی (و شی ای) از لایه ی عقب تر از خودش داشته باشه . یا در واقع مسئول جدا سازی و ارسال داده ی مورد نیاز ، لایه ی فعلی هست .
این قاعده کپسوله سازی (encapsulating) ئه، هر کپسول فقط چیزی رو به بیرون بروز میده که لازم باشه، هر چیزی که به بیرون مربوط نباشه رو باید از دید خارجی پنهان کنه.
یعنی فرضا لایه ی ViewModel که یک لایه جلوتر از View هست ، لازم نیست اطلاعاتی از کنترل های View را بگیره تا اطلاعاتی را که میخواد ، ازش جداسازی کنه . بلکه وظیفه ی جداسازی اطلاعاتی که ViewModel نیاز داره از کنترل ها ، وظیفه ی لایه ی View هست .
و همین طور Model ، نباید اطلاعات کلاسی از نوع ViewModel (و از لایه ی ViewModel) را بگیره تا اطلاعات مورد نیازش را جدا کنه . بلکه وظیفه ی ViewModel هست که اطلاعات مورد نیاز Model را از شی کلاس خودش ، براش جدا کنه و بفرسته .
درسته؟
یعنی این قضیه ربطی به معماری mvvm و حتی شاید ربطی به معماری 3 نداره . درسته؟
بله. چرا مربوط هست. در هر کدوم از این معماری ها کپسوله سازی لایه ها یکی از اهداف اصلی ئه.
اگه درستن ، پس در این صورت ، حتی در معماری 3 لایه هم ، لایه ی Model یا منطق تجاری اش ، از لحاظ به روزرسانی در نسخه های بعدیِ این لایه ، یا از لحاظ انتقال کدهای این لایه و همچنین نگه داریش ، هیچ فرقی با این لایه در معماری mvvm نمیکنه . درسته؟
شما یک معماری n لایه رو در نظر بگیرید، هر لایه بر اساس یکسری قواعد مسئولیت های مجزا داره. هر چقدر که محتویات لایه ها به روزرسانی بشه همچنان مسئولیت ها و قواعد معماری سر جاشه و ثابت میمونه.
پس با این حال ، فرق معماری mvvm با 3 لایه ، فقط در دو لایه ی View با ViewModel هست که اندکی انتقال و نگه داری و به روزرسانی لایه ی View ، نسبت به همین لایه درون معماری 3 لایه ، بهتر میشه .
درست میگم؟
نه. MVVM اولا خودش سه لایه است، ثانیا معماری های سه لایه انواع مختلفی داره و ثالثا هر معماری مزایا و معایب خودش رو داره.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ظاهر قضیه اینه که در فیلد static readonly مقدار خونده و نوشته میشه؟ لااقل یک چیزی از ظاهر نتیجه بگیرید که با قواعد زبان #C منافاتی نداشته باشه.

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

شیء گرایی منافاتی با static بودن نداره. static object x همونقدر شیء ئه که object x شیء ئه. شیء گرایی همیشه سر جاش هست، جایی نقض نمیشه. اگر به متد های DependencyObject توجه کنید می بینید که GetValue و SetCurrentValue و ... متد های static ای نیستند، عملکرد شون به instance اجرا کننده وابستگی داره.

سلامی مجدد
خیلی ممنون استاد :rose:

ببخشید حواسم نبود . همون صرفا خوندنش و یکبار توی این فیلد همون اول نوشته میشه (اون هم با متد DependencyProperty.Register نوشته میشه) .

به هر حال گفتم که . هر چی هست ، مربوط به اون متدهای GetValue و SetValue و SetCurrentValue و اینها هست که نمیدونم و بررسی نکردم که چجوری کار میکنن .

احتمالا مقداری را در یک فیلد یا آرایه ی private (و از این چیزها) به ازای هر فیلدِ ثبت شده ی استاتیکِ مربوط به DependencyProperty ، بریزن . باز هم نمیدونم .


فرضا در Model یک مشخصه Student هست یا یک مشخصه StudentName هست، که جزئی از واسط Model برای ارتباط با ViewModel ئه.
و ثبت مقدار جدید در هر کدوم از این مشخصه ها صرفا بخشی از یک فرایند ئه، نه کل فرایند، بخشی از فرایند ذخیره سازی یک Student جدید، بخشی از فرایند ویرایش یک Student و ... . حالا اگر ViewModel در یکی از ایندو مشخصه مقدار جدیدی ثبت کرد، آیا باید Model بلافاصله اقدام به ذخیره سازی اون مقادیر در پایگاه داده بکنه؟ الزاما خیر. حتما نباید همچین کاری بکنه، الزامی نیست. یعنی اگر Binding ای با هر تغییری در View بلافاصله مقدار مشخصه ای رو در Model تغییر داد، الزاما نباید Model با ذخیره کردن مقدار جدید واکنش نشون بده. که اگر اینکار رو بکنه به مشابه اون نقل قول "That doesn't work well for edit-screens that have a Save/Cancel button"، این واسطی میشه که برای دکمه های Save/Cancel مناسب نیست.

آها . خیلی ممنون استاد .

پاسخ سوال ام رو ندادید. شما الان یک Binding دارید که از View مستقیم رفته به سمت Model. یا Notification ای هم دارید از Model مستقیم به View رسیده. مثال این دو ارتباط چیه که با معماری MVVM هم تناقض نداشته باشه؟

منظورتون تعیین Binding Source (یا DataContext) و کلا منبع Binding هست که به لایه ی ViewModel متصل شه؟
اگه آره ، این را میدونم .

منظورم Binding.Path اش هست که لایه ی Model را هم میتونیم براش در نظر بگیریم . همونطور که در مثال پیوست پروژه ای بنام MVVM_Practies در پست 780 (صفحه ی 39) ، پیوست کردم .

توی همون پروژه هم در کلاس Student که جزء لایه ی Model هست ، اینترفیس INotifyPropertyChanged را پیاده سازی کردیم .

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

استخراج داده از Control یا درج داده در Control رو یا باید خود View انجام بده. و تحت هیچ شرایطی نباید از محدوده ViewModel View خارج بشه و وارد ناحیه Model بشه.

بله. مسئولیت اش با View ئه.

بله. هر لایه مسئولیت خودش رو داره.

این قاعده کپسوله سازی (encapsulating) ئه، هر کپسول فقط چیزی رو به بیرون بروز میده که لازم باشه، هر چیزی که به بیرون مربوط نباشه رو باید از دید خارجی پنهان کنه.

خوب استاد الان جواب های این تیکه در بالا که گفتین ،

بله. چرا مربوط هست. در هر کدوم از این معماری ها کپسوله سازی لایه ها یکی از اهداف اصلی ئه.

با جواب این که یه کم مخالف میشه (اینکه گفتین مربوط هست را میگم) .
پس به معماری mvvm ربطی نداره . بلکه در معماری 3 لایه هم همینطوره که گفته بودم و در جواب قسمت بالا هم تایید کردین.

شما یک معماری n لایه رو در نظر بگیرید، هر لایه بر اساس یکسری قواعد مسئولیت های مجزا داره. هر چقدر که محتویات لایه ها به روزرسانی بشه همچنان مسئولیت ها و قواعد معماری سر جاشه و ثابت میمونه.

نه. MVVM اولا خودش سه لایه است، ثانیا معماری های سه لایه انواع مختلفی داره و ثالثا هر معماری مزایا و معایب خودش رو داره.

این بخش هم که قسمت اولیه ی جوابی که دادید را تایید میکنه . (بله ، میدونم mvvm ، خودش 3 لایه هست) .
پس حرفم حدودا درسته دیگه .
اینکه گفتم "فرق معماری mvvm با 3 لایه ، فقط در دو لایه ی View با ViewModel هست که اندکی انتقال و نگه داری و به روزرسانی لایه ی View ، نسبت به همین لایه درون معماری 3 لایه ، بهتر میشه" .

البته توی انتقال کد تاثیر (یا حداقل اینکه تاثیر چندانی) نداره .
تفاوت دقیق تر این دو معماری (معماری 3 لایه با معماری mvvm) را در زیر بهتر گفته :


مزایای mvvm (نسبت به معماری 3 لایه) :

- نگه داری کد بهتر

- کار کردن با بخش طراح visual studio (یا کار کردن با نرم افزار blender اش) راحت تر هست (که به نظر نویسنده ، این میتونه، مهمترین ویژگی mvvm باشه) .

- قابلیت تست با پیچیدگی های کمتر در ViewModel .


انتقال کد در mvvm هم فرقی با انتقال کد در معماری 3 لایه ، نداره .

تشکر استاد .
 

the_king

مدیرکل انجمن
منظورتون تعیین Binding Source (یا DataContext) و کلا منبع Binding هست که به لایه ی ViewModel متصل شه؟
اگه آره ، این را میدونم .
نه. دو ارتباطی که رسم کرده اید مستقیم از View به Model رسیده یا برعکس. ViewModel ای واسط ارتباط نیست.
منظورم Binding.Path اش هست که لایه ی Model را هم میتونیم براش در نظر بگیریم . همونطور که در مثال پیوست پروژه ای بنام MVVM_Practies در پست 780 (صفحه ی 39) ، پیوست کردم .
اینکه Binding.Path منتهی به تعاریفی در لایه Model میشه درسته، ولی این ارتباط مستقیم نیست که در نمودار از View به Model منتهی بشه.
برای همین در نمودار معماری MVVM بین View و Model ارتباطی نمی بینید، نمودار های MVVM رو در گوگل جستجو کنید، در خیلی هاشون ارتباط Binding مشخص شده، اما در هیچکدوم Binding بین View و Model نیست. اگر ارتباط مستقیمی از هر نوعی بین این دو لایه برقرار بود که MVVM نقض میشد. وقتی شما یک ارتباط مستقیم بین اون دو لایه ترسیم می کنید، قواعد معماری MVVM نقض میشه.
توی همون پروژه هم در کلاس Student که جزء لایه ی Model هست ، اینترفیس INotifyPropertyChanged را پیاده سازی کردیم .
بله. در Model پیاده سازی اش کردید، اما کدوم لایه از اون INotifyPropertyChanged استفاده کرده؟ View یا ViewModel؟ میتوانستید در View به Student و مشخصه هایش و PropertyChanged اش اشاره ای بکنید بدون اینکه MVVM نقض بشه؟ اون INotifyPropertyChanged میتونسته بین Model و ViewModel تعامل داشته باشه، اما نه بین Model و View.
خوب استاد الان جواب های این تیکه در بالا که گفتین ،

با جواب این که یه کم مخالف میشه (اینکه گفتین مربوط هست را میگم) .
هر کدوم از این معماری ها اهداف خودشون رو دارند، اگر هدفی در دو معماری مشترک هست معنی اش این نیست که به یکی شون مربوطه و به اون یکی مربوط نیست.
پس به معماری mvvm ربطی نداره . بلکه در معماری 3 لایه هم همینطوره که گفته بودم و در جواب قسمت بالا هم تایید کردین.
معماری A اهداف خودش رو داره و معماری B اهداف خودش رو. ممکنه یکسری از این اهداف مشترک در هر دو باشند یا نباشند. این دلیل نمیشه که اهداف مشترک به یکی شون مربوط باشه و به اون یکی نباشه.
این بخش هم که قسمت اولیه ی جوابی که دادید را تایید میکنه . (بله ، میدونم mvvm ، خودش 3 لایه هست) .
پس حرفم حدودا درسته دیگه .
اینکه گفتم "فرق معماری mvvm با 3 لایه ، فقط در دو لایه ی View با ViewModel هست که اندکی انتقال و نگه داری و به روزرسانی لایه ی View ، نسبت به همین لایه درون معماری 3 لایه ، بهتر میشه" .
پاسخ دادم که اشتباهه، اما اگر از تصورات اشتباه لذت می برید ببرید.
 

SajjadKhati

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

اینکه Binding.Path منتهی به تعاریفی در لایه Model میشه درسته، ولی این ارتباط مستقیم نیست که در نمودار از View به Model منتهی بشه.

سلامی مجدد
خیلی ممنون استاد :rose:
الان اگه بخوام منظورم را درست برسونم ، چه شکلی باید رسم کنم؟ آخه هر دو شکلی که کشیدم را اشکال گرفتین .

الان منظورم این هست که همونطور میدونید ، Binding ای هست که Binding Path اش (یا همون Binding Source Property اش) در Model هست و Binding Target Property اش در View هست و Binding Source اش در ViewModel هست (مثل همون پروژه ی MVVM_Practies که گفتم) .

الان اگه بخوام در شکل مورد نظر ، همچین موردی را نشون بدم ، یعنی Binding Path ام را که در لایه ی Model هست را نشون بدم ، در همون شکل پست 970 ، فِلِش ای که از View به Model میره (فِلِشِ قرمز رنگ) ، زیر این فِلِش ، بنویسم Binding Path ؟
این جوری خوبه دیگه؟

بله. در Model پیاده سازی اش کردید، اما کدوم لایه از اون INotifyPropertyChanged استفاده کرده؟ View یا ViewModel؟ میتوانستید در View به Student و مشخصه هایش و PropertyChanged اش اشاره ای بکنید بدون اینکه MVVM نقض بشه؟ اون INotifyPropertyChanged میتونسته بین Model و ViewModel تعامل داشته باشه، اما نه بین Model و View.

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

هر کدوم از این معماری ها اهداف خودشون رو دارند، اگر هدفی در دو معماری مشترک هست معنی اش این نیست که به یکی شون مربوطه و به اون یکی مربوط نیست.

معماری A اهداف خودش رو داره و معماری B اهداف خودش رو. ممکنه یکسری از این اهداف مشترک در هر دو باشند یا نباشند. این دلیل نمیشه که اهداف مشترک به یکی شون مربوط باشه و به اون یکی نباشه.

پاسخ دادم که اشتباهه، اما اگر از تصورات اشتباه لذت می برید ببرید.

الان استاد ، توی اون لینک که دادم و متنی که بولد کردم که طرف ، متن زیر را برای مقایسه ی mvvm و معماری 3 لایه میگفت ، درسته؟ :

مزایای mvvm (نسبت به معماری 3 لایه) :

- نگه داری کد بهتر

- کار کردن با بخش طراح visual studio (یا کار کردن با نرم افزار blender اش) راحت تر هست (که به نظر نویسنده ، این میتونه، مهمترین ویژگی mvvm باشه) .

- قابلیت تست با پیچیدگی های کمتر در ViewModel .

درسته دیگه؟
 
آخرین ویرایش:

the_king

مدیرکل انجمن
سلامی مجدد
خیلی ممنون استاد :rose:
الان اگه بخوام منظورم را درست برسونم ، چه شکلی باید رسم کنم؟ آخه هر دو شکلی که کشیدم را اشکال گرفتین .
نمونه نمودارش که در گوگل هست. شما ارتباط رو از طرف View یا Model که شروع کنید باید به ViewModel ختم بشه، ارتباطی ندارید که از View به Model برسه یا برعکس. هر نوع ارتباطی که دارید یک طرفش باید ViewModel باشه.
الان منظورم این هست که همونطور میدونید ، Binding ای هست که Binding Path اش (یا همون Binding Source Property اش) در Model هست و Binding Target Property اش در View هست و Binding Source اش در ViewModel هست (مثل همون پروژه ی MVVM_Practies که گفتم) .

الان اگه بخوام در شکل مورد نظر ، همچین موردی را نشون بدم ، یعنی Binding Path ام را که در لایه ی Model هست را نشون بدم ، در همون شکل پست 970 ، فِلِش ای که از View به Model میره (فِلِشِ قرمز رنگ) ، زیر این فِلِش ، بنویسم Binding Path ؟
این جوری خوبه دیگه؟
نه. Model درگیر نیست. یک طرف ارتباط Binding ئه View ئه و طرف مقابل ViewModel ئه. Model در این ارتباط نه مبدا ئه و نه مقصد، درگیر نیست.
تصویر binding mvvm رو در گوگل جستجو کنید، ببینید مبدا و مقصد Binding کجا است؟ نمیشه که همه شون اشتباه رسم کرده باشند و فقط شما درست رسم کرده باشید.
لازم به فراخونی و دسترسی صریح به این رویداد نیست که حالا از View بخوایم به این رویدادش دسترسی پیدا کنیم یا نکنیم (قبلا که خودتون توضیح داده بودید) .
نموداری که رسم کرده اید رو ببینید. طبق رسم شما یک نوع ارتباط مستقیم بین View و Model میسر هست، چیزی که طبق قواعد معماری MVVM ممکن نیست. این چیزی که رسم می کنید هر معماری ای که باشه معماری MVVM نیست، نمیتونه نمودار معماری MVVM باشه.
الان استاد ، توی اون لینک که دادم و متنی که بولد کردم که طرف ، متن زیر را برای مقایسه ی mvvm و معماری 3 لایه میگفت ، درسته؟ :

مزایای mvvm (نسبت به معماری 3 لایه) :

- نگه داری کد بهتر

- کار کردن با بخش طراح visual studio (یا کار کردن با نرم افزار blender اش) راحت تر هست (که به نظر نویسنده ، این میتونه، مهمترین ویژگی mvvm باشه) .

- قابلیت تست با پیچیدگی های کمتر در ViewModel .

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

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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
نمونه نمودارش که در گوگل هست. شما ارتباط رو از طرف View یا Model که شروع کنید باید به ViewModel ختم بشه، ارتباطی ندارید که از View به Model برسه یا برعکس. هر نوع ارتباطی که دارید یک طرفش باید ViewModel باشه.

نه. Model درگیر نیست. یک طرف ارتباط Binding ئه View ئه و طرف مقابل ViewModel ئه. Model در این ارتباط نه مبدا ئه و نه مقصد، درگیر نیست.
تصویر binding mvvm رو در گوگل جستجو کنید، ببینید مبدا و مقصد Binding کجا است؟ نمیشه که همه شون اشتباه رسم کرده باشند و فقط شما درست رسم کرده باشید.

نموداری که رسم کرده اید رو ببینید. طبق رسم شما یک نوع ارتباط مستقیم بین View و Model میسر هست، چیزی که طبق قواعد معماری MVVM ممکن نیست. این چیزی که رسم می کنید هر معماری ای که باشه معماری MVVM نیست، نمیتونه نمودار معماری MVVM باشه.

سلامی مجدد
خیلی ممنون استاد :rose:

تصویر زیر را ببینید :


MVVM 2 - Complex.jpg


خوب اونی که شما میگین اون طور رسم کردن ، اونها ، قسمت Binding Path (یا همون Binding Source Property) را در نظر نگرفتن (و احتمالا فقط تا Binding Source ، مد نظرشون بوده) .
اما من قصد دارم Binding Path (یا همون Binding Source Property) را هم در شکل ، در نظر بگیرم .

با در نظر گرفتن Binding Path ، در شکل بالا ، هم Binding Source ، در ViewModel در نظر گرفته شد و هم Binding Path در Model در نظر گرفته شد بدون اینکه اتصال مستقیمی بین Binding در View و Model نمایش داده بشه .
الان این شکل دیگه درسته دیگه؟

اما هنوز دقیق متوجه نشدم که چرا در قسمت INotifyPropertyChanged ، یکی از Model به ViewModel و یکی دیگه هم از ViewModel به View رسم میشه؟
آخه اولا که بصورت صریح ، قرار نیست که اصلا به این رویدادش در لایه های دیگه ، متدی متصل کنن . دوما ، وقتی رویداد PropertyChanged اش که در Model هست ، فراخونی شد ، خوب شی Binding ، مطلع میشه از اجرای این رویداد دیگه . شی Binding هم که در لایه ی View به عنوان Binding Target Property تعریف و مقداردهی شد . پس طبعا شیِ Binding در لایه ی View ، حتی این طور که مشخص هست ، حتی بدون نیاز به واسط ViewModel ، خبر دار میشه دیگه . درست نیست؟

برای بار چندم میگم. اشتباهه. اشتباه یعنی درست نیست. اولا MVVM خودش معماری سه لایه است، چیزی که خودش سه لایه است رو با خودش که نمی توانید مقایسه کنید. باید با معماری های مشخصی مقایسه بشه، یا معماری هایی بجز سه لایه ها، یا با معماری های سه لایه دیگه.
چنار رو که نمی توانید با درخت مقایسه کنید، چنار خودش درخت ئه. پرتقال رو که نمی توانید با میوه مقایسه کنید.
ثانیا MVVM رو کلی مقایسه نمی کنه، داره در پلتفرم WPF مقایسه می کنه، مقایسه کلی معماری MVVM مستقل از پلتفرم که نیست.
ثالثا معلوم نیست اصلا با کدوم معماری های سه لایه مقایسه اش می کنه که البته این رو در جواب هم واضح گفته.
رابعا این مقایسه X و Y نیست، مزایای X در یک پلتفرم A نسبت به Y ئه که معلوم هم نیست Y چیه.
اشکال کار اینجا است که حتی پاسخی که داده رو هم درست نخوندید، حتی از موضوع سوال ایراد گرفته.
خامسا مقایسه دو مورد شامل مزایا و معایب میشه، نه فقط مزایا.

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

میدونم MVVM ، خودش 3 لایه هست .
منظور از معماری 3 لایه ، همون 3 tier architect (یا 3 layer architect) هست .
بله ، MVVM ، همون هست منتها ویژگیِ اضافه تری که داره اینه که لایه ی View که در معماری 3 لایه ، یه دونه هست ، در MVVM ، به دو لایه ی View و ViewModel تبدیل شد که میدونید .
یعنی یه ویژگیِ اضافه تری داره .

در واقع به قول خودتون کلمه ی تفاوت شاید درست نباشه (که البته چندان هم غلط نیست) . کلمه ی اینکه ویژگی های اضافه ترِ MVVM نسبت به معماری 3 لایه چیه ، بهتر باشه .
مثل فرضا تفاوت کلاس Windows با کلاس Control در wpf میمونه . هر چند شیِ کلاس Windows ، همون شیِ Control هست منتها ویژگی های بیشتری داره .

البته mvvm شاید 4 لایه هم باشه . دقیق نمیدونم . چون لایه ی Model در mvvm ، همون رفتار را میشه باهاش کرد که خودِ این لایه ، 2 لایه ی جداگانه برای منطق تجاری و یه لایه ی دیگه برای دیتابیس باشن .

===============

به هر حال ، الان ویژگی های اضافه ترِ (یا تفاوت یا هر عبارت دیگه ای ...) MVVM نسبت به معماری 3 لایه (که اضافه شدن لایه ی ViewModel هست) چیه؟

تشکر استاد
 

the_king

مدیرکل انجمن
سلامی مجدد
خیلی ممنون استاد :rose:

تصویر زیر را ببینید :


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


خوب اونی که شما میگین اون طور رسم کردن ، اونها ، قسمت Binding Path (یا همون Binding Source Property) را در نظر نگرفتن (و احتمالا فقط تا Binding Source ، مد نظرشون بوده) .
اما من قصد دارم Binding Path (یا همون Binding Source Property) را هم در شکل ، در نظر بگیرم .

با در نظر گرفتن Binding Path ، در شکل بالا ، هم Binding Source ، در ViewModel در نظر گرفته شد و هم Binding Path در Model در نظر گرفته شد بدون اینکه اتصال مستقیمی بین Binding در View و Model نمایش داده بشه .
الان این شکل دیگه درسته دیگه؟
Binding Notification نه معادل INotifyPropertyChanged ئه و نه INotifyPropertyChanged وابستگی به Binding داره، برای همین در عبارت Binding Notification اون Binding اش هم اضافیه و نامرتبط.
ارتباط INotifyPropertyChanged با عنوان Notification هم بین View و ViewModel یا بین Model و ViewModel هیچ ایرادی نداره.
اما Binding Path دیگه چه نوع ارتباطی است که بخواد بین ViewModel و Model باشه؟ Binding.Path و PropertyPath برای استفاده در XAML طراحی شده، برای ارتباط بین DependencyProperty در DependencyObject ها است. در ViewModel مگه این چیز ها هست؟
اما هنوز دقیق متوجه نشدم که چرا در قسمت INotifyPropertyChanged ، یکی از Model به ViewModel و یکی دیگه هم از ViewModel به View رسم میشه؟
چون هر کدوم واسط کاربری خودشون رو دارند که احتمالا شامل یکسری مشخصه است.
در هر کدوم چه Model و چه ViewModel و چه View ممکنه واسطی باشه با یکسری مشخصه که داخل لایه خودشون یا لایه دیگری مخاطبی داشته باشند مثل CollectionView ، مثل DataRowView و ... که بخواد زمان تغییر مقدار این مشخصه ها مطلع بشه، نه فقط بخاطر Binding، خود Binding فقط یکی از استفاده کننده های اون INotifyPropertyChanged ئه. برای مطلع شدن از این تغییرات هم وجود INotifyPropertyChanged لازمه.
آخه اولا که بصورت صریح ، قرار نیست که اصلا به این رویدادش در لایه های دیگه ، متدی متصل کنن . دوما ، وقتی رویداد PropertyChanged اش که در Model هست ، فراخونی شد ، خوب شی Binding ، مطلع میشه از اجرای این رویداد دیگه . شی Binding هم که در لایه ی View به عنوان Binding Target Property تعریف و مقداردهی شد . پس طبعا شیِ Binding در لایه ی View ، حتی این طور که مشخص هست ، حتی بدون نیاز به واسط ViewModel ، خبر دار میشه دیگه . درست نیست؟
اولا وجود یا عدم وجود که Binding دلیل پیاده سازی INotifyPropertyChanged نیست، Binding هم تنها استفاده کننده INotifyPropertyChanged نیست. ثانیا ViewModel منطق و روال های خودش رو داره که باید اجرایی باشند، اگر تغییری در Model رخ داد، باید ViewModel بتونه بدون واسطه مطلع بشه، هدف فقط مطلع کردن View که نیست، ViewModel هم هست. چه View مطلع بشه و چه نشه، چه اصلا View ای در کار باشه و چه نباشه.
میدونم MVVM ، خودش 3 لایه هست .
منظور از معماری 3 لایه ، همون 3 tier architect (یا 3 layer architect) هست .
توضیحات اون معماری سه لایه رو در منابع مختلف بخونید، در مورد چی صحبت می کنه؟ در مورد اینکه سه لایه "واسط کاربری" و "منطق کسب و کار" و "پایگاه داده" مجزا باشند، ارتباط شون با هم Client-Server ای باشه، و نه الزاما به شکل فیزیکی در سرور های مختلف، بلکه حداقل به شکل منطقی مجزا باشند. شما در MVVM لایه "واسط کاربری" تون جدا است، لایه "پایگاه داده" تون هم جدا است و "منطق کسب و کار" هم میتونه در لایه ViewModel محدود شده باشه، برای همینه که MVVM گونه ای از اون معماری سه لایه است. نه صرفا به این خاطر که سه تا لایه داره، بخاطر توصیف معماری اش.
بله ، MVVM ، همون هست منتها ویژگیِ اضافه تری که داره اینه که لایه ی View که در معماری 3 لایه ، یه دونه هست ، در MVVM ، به دو لایه ی View و ViewModel تبدیل شد که میدونید .
یعنی یه ویژگیِ اضافه تری داره .
من همچین چیزی که شما میگید نمیدونم. در معماری سه لایه واسط کاربری یکی از لایه ها است که بهش Presentation هم میگن. در MVVM هم صرفا لایه View برای واسط کاربری است. ViewModel که واسط کاربری نیست. مسئولیت های واسط کاربری در MVVM با کدوم لایه است؟ با View.
چطوری واسط کاربری به دو لایه View و ViewModel تبدیل بشه وقتی واسط کاربری فقط در View قرار داره و مسئولیت هایش رو به لایه دیگری واگذار نکرده؟
واسط کاربری نمیتونه دو بخش بشه، واسط کاربری همون View ئه. چیزی که در ViewModel قرار داره مربوط به ارتباط Model با View ئه یعنی نه مسئولیت های واسط کاربری است و نه مسئولیت های پایگاه داده. اگر غیر از این بود که MVVM دیگه گونه ای از معماری سه لایه نبود.
در واقع به قول خودتون کلمه ی تفاوت شاید درست نباشه (که البته چندان هم غلط نیست) . کلمه ی اینکه ویژگی های اضافه ترِ MVVM نسبت به معماری 3 لایه چیه ، بهتر باشه .
مثل فرضا تفاوت کلاس Windows با کلاس Control در wpf میمونه . هر چند شیِ کلاس Windows ، همون شیِ Control هست منتها ویژگی های بیشتری داره .
بله. این درسته. ویژگی ها بیشتری داره. برای همین جایی نمی بینید که کلاس Windows رو با Control مقایسه کنند. همانطور که پرتقال رو با میوه مقایسه نمی کنند.
البته mvvm شاید 4 لایه هم باشه . دقیق نمیدونم . چون لایه ی Model در mvvm ، همون رفتار را میشه باهاش کرد که خودِ این لایه ، 2 لایه ی جداگانه برای منطق تجاری و یه لایه ی دیگه برای دیتابیس باشن .
نه. معماری MVVM اگر شامل 4 لایه باشه باید مسئولیت های لایه چهارم رو تفکیک کنه، محدودیت های ارتباطی اش رو مشخص کنه و ...
شما ممکنه بر اساس منطقی بیایید داخل یک لایه چند زیر لایه در نظر بگیرید، اما محدودیتی در MVVM نیست که شما رو وادار به اینکار کرده باشه. اینکه شما چطور زیر لایه میسازید و با زیرلایه ها رفتار می کنید ربطی به معماری MVVM و قواعدش نداره.
به هر حال ، الان ویژگی های اضافه ترِ (یا تفاوت یا هر عبارت دیگه ای ...) MVVM نسبت به معماری 3 لایه (که اضافه شدن لایه ی ViewModel هست) چیه؟
در موقعیت منطق تجاری ئه. MVVM روی این تاکید داره که ارتباط مستقیمی بین واسط کاربری با پایگاه داده نباشه، یعنی همانطور که لایه Application در این میان بود، اما منطق تجاری رو محدود به لایه Model نمی کنه. منطق تجاری میتونه تماما در Model باشه، یا بخشی اش در ViewModel باشه. MVVM تاکید روی این داره که داده از Model تامین بشه و در Model مدیریت بشه و View هم تنها بخش مرتبط با واسط کاربری باشه و ایندو ارتباط مستقیمی هم با هم نداشته باشند و ViewModel رابط ایندو باشه. اما محل پردازش داده و منطق تجاری رو محدود به یک لایه خاص مثل Model نمی کنه، با این استدلال که اگر داده ای که واسط Model ارائه می کنه مناسب View نبود یا برعکس، ViewModel پردازش لازم رو روی داده انجام بده تا ایندو لایه کاملا مجزا با هم سازگار بشوند. نتیجه اش اینه که ViewModel این امکان رو داره که Model ها و View هایی رو با هم سازگار کنه که با واسط فعلی شون الزاما سازگار نیستند. ViewModel قراره یک لایه سبکی ای باشه که این امکان رو طراحان نرم افزار بده تا به سادگی و در مدت زمان کم Model های مختلف رو با View های مختلف هماهنگ کنند. اما در معماری سه لایه Application خودش مسئولیت قابل توجهی داره، یک لایه بزرگ و پیچیده است، به سادگی نمیشه تغییرش داد. اگر تغییری در لایه Presentation یا Database رخ بده، دستکاری لایه سنگین Application لازم میشه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
Binding Notification نه معادل INotifyPropertyChanged ئه و نه INotifyPropertyChanged وابستگی به Binding داره، برای همین در عبارت Binding Notification اون Binding اش هم اضافیه و نامرتبط.
ارتباط INotifyPropertyChanged با عنوان Notification هم بین View و ViewModel یا بین Model و ViewModel هیچ ایرادی نداره.

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

اما Binding Path دیگه چه نوع ارتباطی است که بخواد بین ViewModel و Model باشه؟ Binding.Path و PropertyPath برای استفاده در XAML طراحی شده، برای ارتباط بین DependencyProperty در DependencyObject ها است. در ViewModel مگه این چیز ها هست؟

Binding.Path ، برای ارتباط بین Binding Source Property (که در اینجا ، این پروپرتی ، در لایه ی Model مد نظرم هست . مثل Binding ای که از پروپرتیِ FirstName در اون پروژه ی MVVM_Practies به پروپرتیِ Text ئه TextBox انجام شد) با Binding Source Object (که در اینجا ، این شی ، در لایه ی ViewModel مد نظرم هست . مثل پروپرتیِ Student در همون پروژه که در ViewModel) هست تا مشخص بشه که کدوم پروپرتی از Binding Source Object ، مد نظرمون هست .

که Binding Source Property ، میتونه DependencyProperty هم نباشه و Binding Source Object ، میتونه DependencyObject هم نباشه . و Binding.Path در سی شارپ هم میتونه استفاده بشه که میدونیم .


basic-data-binding-diagram.png



چون هر کدوم واسط کاربری خودشون رو دارند که احتمالا شامل یکسری مشخصه است.
در هر کدوم چه Model و چه ViewModel و چه View ممکنه واسطی باشه با یکسری مشخصه که داخل لایه خودشون یا لایه دیگری مخاطبی داشته باشند مثل CollectionView ، مثل DataRowView و ... که بخواد زمان تغییر مقدار این مشخصه ها مطلع بشه، نه فقط بخاطر Binding، خود Binding فقط یکی از استفاده کننده های اون INotifyPropertyChanged ئه. برای مطلع شدن از این تغییرات هم وجود INotifyPropertyChanged لازمه.

اولا وجود یا عدم وجود که Binding دلیل پیاده سازی INotifyPropertyChanged نیست، Binding هم تنها استفاده کننده INotifyPropertyChanged نیست. ثانیا ViewModel منطق و روال های خودش رو داره که باید اجرایی باشند، اگر تغییری در Model رخ داد، باید ViewModel بتونه بدون واسطه مطلع بشه، هدف فقط مطلع کردن View که نیست، ViewModel هم هست. چه View مطلع بشه و چه نشه، چه اصلا View ای در کار باشه و چه نباشه.

حدودا متوجه شدم .
ممنون استاد .

توضیحات اون معماری سه لایه رو در منابع مختلف بخونید، در مورد چی صحبت می کنه؟ در مورد اینکه سه لایه "واسط کاربری" و "منطق کسب و کار" و "پایگاه داده" مجزا باشند، ارتباط شون با هم Client-Server ای باشه، و نه الزاما به شکل فیزیکی در سرور های مختلف، بلکه حداقل به شکل منطقی مجزا باشند. شما در MVVM لایه "واسط کاربری" تون جدا است، لایه "پایگاه داده" تون هم جدا است و "منطق کسب و کار" هم میتونه در لایه ViewModel محدود شده باشه، برای همینه که MVVM گونه ای از اون معماری سه لایه است. نه صرفا به این خاطر که سه تا لایه داره، بخاطر توصیف معماری اش.

منطق کسب و کار (تجاری) ، مگه همون لایه ی Model در MVVM نیست؟
ViewModel هم ممکنه جزء لایه ی منطق تجاری قرار بگیره؟!
ViewModel که وظیفه ی ارتباط View با Model را داره فقط .

من آخر متوجه نشدم این چه اسم هایی هه که روشون با شروعِ "منطق" میذارن . از "منطق تجاری" گرفته تا "منطق ارائه" و فکر کنم یه چند تا منطق دیگه هم باشن که اسم شون را یاد نگرفتم .
آخه منطق تجاری ، مگه با این لایه ، پول درمیارن که با منطق ارائه پول درنمیارن که این اسم های بی مثما را براشون انتخاب کردن! این چه اسم هایی هست خداییش !

من همچین چیزی که شما میگید نمیدونم. در معماری سه لایه واسط کاربری یکی از لایه ها است که بهش Presentation هم میگن. در MVVM هم صرفا لایه View برای واسط کاربری است. ViewModel که واسط کاربری نیست. مسئولیت های واسط کاربری در MVVM با کدوم لایه است؟ با View.
چطوری واسط کاربری به دو لایه View و ViewModel تبدیل بشه وقتی واسط کاربری فقط در View قرار داره و مسئولیت هایش رو به لایه دیگری واگذار نکرده؟
واسط کاربری نمیتونه دو بخش بشه، واسط کاربری همون View ئه. چیزی که در ViewModel قرار داره مربوط به ارتباط Model با View ئه یعنی نه مسئولیت های واسط کاربری است و نه مسئولیت های پایگاه داده. اگر غیر از این بود که MVVM دیگه گونه ای از معماری سه لایه نبود.

بله . درست میگید . منظور من هم همین بود . اما بیان ام شاید زیاد درست مطرح نکرده بودم .
حالا استاد زیاد به واژه هایی که میگم ، اشکال نگیرید (البته بجز اونهایی را که در تصاویر و شکل ها ، مینویسم که مهم هستن) . منظورم را که متوجه میشید . شما ، منظورم را در نظر بگیرید .

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

البته الان شاید بگید که وقتی واژگان را غلط بگم ، منظورم هم بهتون غلط میرسه تا متوجه بشید که منظورم چیه . اما به هر حال اگه زمانی متوجه میشید که منظورم در واژگان غلطی ارائه شد ، علاوه بر اینکه مثل الان میگید که این واژه ها غلط هستن ، بی زحمت جواب منظور اصلی ام را هم بدید .

ببخشیدها . تشکر

---------------------

هر چند توی چند تا مقاله ی انگلیسی هم دیده بودم که میگفتن که لایه ی Presentation در MVVM ، به دو لایه ی View و ViewModel تقسیم شده اما شما درست میگید .
منظور من هم همین که گفتید ، بود .

بله. این درسته. ویژگی ها بیشتری داره. برای همین جایی نمی بینید که کلاس Windows رو با Control مقایسه کنند. همانطور که پرتقال رو با میوه مقایسه نمی کنند.

نه. معماری MVVM اگر شامل 4 لایه باشه باید مسئولیت های لایه چهارم رو تفکیک کنه، محدودیت های ارتباطی اش رو مشخص کنه و ...
شما ممکنه بر اساس منطقی بیایید داخل یک لایه چند زیر لایه در نظر بگیرید، اما محدودیتی در MVVM نیست که شما رو وادار به اینکار کرده باشه. اینکه شما چطور زیر لایه میسازید و با زیرلایه ها رفتار می کنید ربطی به معماری MVVM و قواعدش نداره.

آها متوجه شدم .
ممنون .

در موقعیت منطق تجاری ئه. MVVM روی این تاکید داره که ارتباط مستقیمی بین واسط کاربری با پایگاه داده نباشه، یعنی همانطور که لایه Application در این میان بود، اما منطق تجاری رو محدود به لایه Model نمی کنه. منطق تجاری میتونه تماما در Model باشه، یا بخشی اش در ViewModel باشه.

MVVM تاکید روی این داره که داده از Model تامین بشه و در Model مدیریت بشه و View هم تنها بخش مرتبط با واسط کاربری باشه و ایندو ارتباط مستقیمی هم با هم نداشته باشند و ViewModel رابط ایندو باشه.

اول استاد این طور که شما دارید میگید که بخشی از منطق تجاری میتونه در لایه ی ViewModel هم باشه ، پس اول بذارید ببینم واژه ی "منطق تجاری" که در ذهنم هست را درست میدونم یا ماجرا چیز دیگه ای هست؟

منطق تجاری ، طبق چیزی که در لینک زیر هست :


The Business Logic layer handles all of the business rules, calculations and actual logic within your application that makes it actually "do" things and it may often use some of the objects retrieved from your data-access layer.

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

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

بنابراین ها ، ViewModel ، نباید نقشی در حتی بخشی از منطق تجاری داشته باشه که .


اما (MVVM) محل پردازش داده و منطق تجاری رو محدود به یک لایه خاص مثل Model نمی کنه، با این استدلال که اگر داده ای که واسط Model ارائه می کنه مناسب View نبود یا برعکس، ViewModel پردازش لازم رو روی داده انجام بده تا ایندو لایه کاملا مجزا با هم سازگار بشوند.

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

آها پس منطق تون برای اینکه میگید بخشی از منطق تجاری ، ممکنه در ViewModel باشه ، این تیکه که بولد کردم هست؟

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

ادامه ی این پست را در پست بعدی میذارم (چون بخاطر طولانی بودن ، در یک پست ، جا نمیشه) .
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ViewModel قراره یک لایه سبکی ای باشه که این امکان رو به طراحان نرم افزار بده تا به سادگی و در مدت زمان کم ، Model های مختلف رو با View های مختلف هماهنگ کنند. اما در معماری سه لایه ، Application خودش مسئولیت قابل توجهی داره، یک لایه بزرگ و پیچیده است، به سادگی نمیشه تغییرش داد. اگر تغییری در لایه Presentation یا Database رخ بده، دستکاری لایه سنگین Application لازم میشه.

آها . همین رو میخواستم بدونم . به نظرم چیزی که دنبالش میگشتم ، همین خطی که بولد کردم ، هست .
البته Model در MVVM ، با لایه ی "منطق تجاری" و لایه ی مربوط به "دیتابیس" در معماری 3 لایه ، فرقی نداره (بجز حالا فرضا بخشی از Model که در MVVM ممکنه در ViewModel بره) . درسته؟

اگه آره ، پس در MVVM نسبت به معماری 3 لایه ، صرفا بحث سازگار کردنِ بخشِ View یا منطق ارائه ، با Model هست . یعنی به عبارتی تفاوت MVVM (یا هر عبارت دیگه ای که میگید) با معماری 3 لایه ، اینه که در MVVM ، راحت تر و سریعتر لایه ی View را با لایه ی Model میشه هماهنگ کرد (معکوس اش ، نسبت به معماری 3 لایه ، فرقی نداره) .

چون شما در معماری 3 لایه ، در لایه ی منطق تجاری و لایه ی دیتابیس ، هر چیزی که داشته باشید ، عدل ، همه ی اینها را به عنوان لایه ی Model میتونید در یه پروژه ی دیگه در معماری MVVM منتقل کنید بدون هیچ تغییری در این لایه ها .

بنابراین فقط بحث هماهنگ کردن لایه ی View (و انتقالش و هماهنگ کردنش) با لایه ی Model هست که لایه ی ViewModel ، این هماهنگی را راحت تر و سریعتر میکنه .

درسته؟
تشکر استاد :rose:
ببخشید زیاد شد .
 

the_king

مدیرکل انجمن
منطق کسب و کار (تجاری) ، مگه همون لایه ی Model در MVVM نیست؟
معادلش که نیست که بگید همونه، چون منطق کسب و کار و پایگاه داده دو لایه مجزای معماری سه لایه هستند با دو مسئولیت متفاوت که در MVVM لایه Model شامل اون پایگاه داده است در کنار منطق تجاری، اما این درسته که در MVVM لایه Model یا تمامی منطق کسب و کار یا حداقل بخش عمده اون رو در بر خواهد داشت.
ViewModel هم ممکنه جزء لایه ی منطق تجاری قرار بگیره؟!
اگر MVVM رو بخواهید با تعاریف معماری سه لایه تفسیر کنید، بله، چون ViewModel لایه واسط بین Presentation و Database ئه که تنها راه ارتباطی این دو لایه است و طبعا طبق معماری سه لایه در اون لایه Application (لایه منطق تجاری) قرار میگیره. اما طبق تعاریف خود MVVM تفکیک بین منطق تجاری و پایگاه داده موضوعیت نداره. قراره منطق تجاری و پایگاه داده تحت عنوان لایه Model از واسط کاربری تفکیک شده باشه، حالا اینکه خودشون چقدر از هم تفکیک منطقی شده باشند برای MVVM مهم نبوده. بنابر این ViewModel طبق معماری MVVM باید شامل منطقی باشه که داده رو برای واسط کاربری آماده کنه یا برعکس، یعنی Presentation Logic و منطق تجاری طبق تعاریف MVVM در Model قرار میگیره.
ViewModel که وظیفه ی ارتباط View با Model را داره فقط .
دقیقا. این برقراری ارتباط مثل آداپتور ئه، فقط یک سیم کشی ساده نیست، مدار داره، منطق داره، تبدیل داده داره و ... برای همین وظیفه ViewModel میتونه شامل پردازش داده ای باشه که باید از نوع فلان به بهمان تبدیل بشه، یا با روالی منطق ای برای سازگاری واسط فلان با بهمان داشته باشه.
من آخر متوجه نشدم این چه اسم هایی هه که روشون با شروعِ "منطق" میذارن . از "منطق تجاری" گرفته تا "منطق ارائه" و فکر کنم یه چند تا منطق دیگه هم باشن که اسم شون را یاد نگرفتم .
دلیلش اینه که اینها مدل معماری رو از دید کاربردی و تجاری تحلیل می کنند، نه از دید داخلی یک فرایند نرم افزاری یا از دید داخل یک نرم افزار یا پلتفرم. این مدل ها از دید تجاری در دنیای واقعی توصیف میشه، نه از دید نرم افزار و آنچه در WPF و کد #C میگذره. اون چیزی که شما به عنوان طراح یک نرم افزار برای کسب و کاری از محیط مدل سازی می کنید با چیزی که سرمایه گذار در اون کسب و کار مدل سازی می کنه دو دنیای کاملا متفاوت دارند.
آخه منطق تجاری ، مگه با این لایه ، پول درمیارن که با منطق ارائه پول درنمیارن که این اسم های بی مثما را براشون انتخاب کردن! این چه اسم هایی هست خداییش !
دقیقا همینه. این مدلها قراره محیط رو برای سرمایه گذار توصیف کنند، تجارت ئه، این معماری ها برای تجارت الکترونیک طراحی شدند که طراحان سریعتر و راه تر محیطی رو طراحی کنند که ازش پول دربیاورند. اگر منفعت مالی نباشه که دیگه اهمیتی نمیدن که پروژه یک سال طول بکشه یا ده سال.
اول استاد این طور که شما دارید میگید که بخشی از منطق تجاری میتونه در لایه ی ViewModel هم باشه ، پس اول بذارید ببینم واژه ی "منطق تجاری" که در ذهنم هست را درست میدونم یا ماجرا چیز دیگه ای هست؟
منطق تجاری ، طبق چیزی که در لینک زیر هست :




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

الان این تعریف که اون کرد و این ترجمه از منطق تجاری ، درسته؟
صورت مساله رو ساده کنید، بر اساس ارتباط بین واسط کاربری و پایگاه داده هر کاری که در نرم افزار انجام می دهید در سه گروه تفکیک میشه، یا مرتبط با پایگاه داده است، یا مرتبط با واسط کاربری، و هر چیزی که موند منطق تجاری ئه. اگر منطق تجاری رو حذف کنید یا بیخودی دارید تنظیماتی رو در واسط کاربری به کاربر نشون می دهید و بهش اجازه تغییر شون رو می دهید که تغییرشون هم تاثیر خاصی نداره، یا بیخودی داده هایی رو از پایگاه داده میخونید و یا در پایگاه داده می نویسید که اونها هم جایی کاربردی ندارند. چه چیزی باعث میشه این نرم افزار کار مفیدی انجام بده؟ اون منطق تجاری.
اگه درسته ، من فقط یاد لایه ی Model از این تعریف میافتم . نقشی برای لایه ی ViewModel برای این تعریف نمیبینم .
نکته اینجا است، شما موقعیت تمامی جزئیات نقشه یک شهر رو در پایگاه داده دارید، منطق تجاری ای هم دارید که میتونه جزئیات یک ناحیه از این نقشه رو بر اساس موقعیت مکانی جستجو و ارائه کنه. یک واسط کاربری هم دارید که میتونه ناحیه ای از نقشه رو به کاربر نشون بده یا آدرسی رو جستجو کنه.
اما این دو تا به تنهایی مثل شارژر و گوشی هستند، تا کابلی بین شون نباشه به هم متصل نمیشن. باید ViewModel ای باشه که سازگار با اون Model و اون View بتونه ارتباط بین دو واسط رو برقرار کنه. وگرنه Model و View نه ارتباطی با هم دارند و نه قراره داشته باشند. همانطور که در معماری سه لایه بین Database و Presentation ارتباط مستقیمی نمی بینید، Presentation نمیتونه مستقیم از Database داده بخونه و نمایش بده، یا داده از واسط کاربری بفرسته تا در Database ذخیره بشه. بین شون Application ای هست.

ضمن اینکه قبلا بارها گفته بودید و در همینجا هم گفتید که لایه ی ViewModel ، صرفا برای ارتباط بین View با Model و صرفا یک رابطی هست بین شون (و هیچ کار اضافه تری انجام نمیده) .

بنابراین ها ، ViewModel ، نباید نقشی در حتی بخشی از منطق تجاری داشته باشه که .
اینکه ViewModel منطق ای برای تبدیل داده بین View و Model داشته باشه کار اضافه نیست، جزئی از وظایفشه.
ViewModel باید داده ای که Model ارائه می کنه رو با View سازگار کنه، و برعکس. یعنی برای تبدیل داده میتونه پردازش داده انجام بده، چیزی که در MVVM در سمت View تحت عنوان Presentation Logic مشخص شده. اما در معماری سه لایه Application فقط منطق تجاری از نوع خاص Business که نیست، یک اسم دیگه اش لایه کلی Logic ئه، هر Logic ای که بین Database و Presentation قرار بگیره، برای همین منطقی که ViewModel ارائه می کنه در محدوده Application قرار داره.
آها پس منطق تون برای اینکه میگید بخشی از منطق تجاری ، ممکنه در ViewModel باشه ، این تیکه که بولد کردم هست؟
بله. دقت کنید که در معماری سه لایه ما لایه ای داریم با عنوان Application که فقط business logic نیست، logic tier ئه.
نمیدونم . آخه باز هم با این حال ، کار این لایه ، صرفا هماهنگ کردنِ دو لایه ی دیگه (View با Model) هست .
هماهنگ کردن هم چندان با تعریف "منطق تجاری" ، شاید سازگار نباشه .
شما منطق تجاری که فقط یکی از منطق ها است رو معادل کل وظایف لایه Application در نظر گرفته اید، توجه کنید که Application قراره رابط بین Presentation و Database باشه، در MVVM کدوم لایه اینکار رو می کنه؟
 

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

بالا