PDA

View Full Version : متغیر global در برنامه نویسی شیء گرا؟



smt1383
شنبه 22 اسفند 1388, 08:34 صبح
با سلام خدمت دوستان
در یکی از تاپیک ها خواندم که استفاده از متغیر گلوبال با اساس برنامه نویسی شیء گرا منافات دارد. اما دلیل آنرا نفهمیدم. ممنون می شوم اگر دوستان در این زمینه توضیح بدهند.
با تشکر

saed2006
شنبه 22 اسفند 1388, 09:57 صبح
بحث پنهان سازی اطلاعات زیر سوا ل میره

sky_in_iran
شنبه 22 اسفند 1388, 11:43 صبح
سلام دوست عزيز
استادsaed2006 (http://barnamenevis.org/forum/member.php?u=12545) ميشه بيشتر توضيح بدين اين سوال در خيلي از تاپيك ها مطرح ميشه حالا به عناوين مختلف ارسال متغير از يك فرم به فرم ديگر يا چيزايه ديگه علاوه بر رد اين مسئله كه متغير عمومي نباشه ميگن از متغير static هم استفاده نشه هركيم سوال ميكنه چون اين سوال قبلا مطرح شده مسئولين محترم تاپيك و پاك مي كنن اما كسي جواب كامل و دقيق نميده و همه پاس ميدن به گذشته و تاپيك هاي قبل زياد جستجو كردم اما مطلب قابل ذكري كه پاسخگو باشه پيدا نكردم لطفا كامل و با چرايي توضيح بديد ممنون ميشم
موفق باشيد

Sajjad.Aghapour
شنبه 22 اسفند 1388, 13:12 عصر
چندین بار در این مورد بحث شده است.جستجو کنید مطالب مفیدی پیدا خواهید کرد..

http://barnamenevis.org/forum/showthread.php?t=181375
و چندین مورد دیگه...

موفق باشید/

smt1383
دوشنبه 24 اسفند 1388, 08:07 صبح
با تشکر از توضیحات دوستان
تا حد زیادی قانع شدم که استفاده از متغیر گلوبال، کار درستی نیست. آیا من درست فهمیدم که در برنامه نویسی شی گرا هر چه بین فرم ها و کلاسها اطلاعات کمتری رد و بدل شود، برنامه نویسی اصولی تری انجام گرفته است.
بگذارید سؤالم را با یک مثال مطرح کنم. فرم اصلی برنامه من Form1 است. یک کلاس برای ارتباط با پورت سریال تعریف کرده ام به نام Serial_communication چون در فرم اصلی مرتب با پورت سریال در ارتباطم یک نمونه از کلاس Serial_communication به نام SC ساخته ام و با متدهای آن کار می کنم. حال ممکن است به فرم Form2 بروم که در آن هم نیاز به ارتباط با پورت سریال دارم . آیا کار اصولی این است که در Form2 دوباره یک نمونه از کلاس Serial_communication بسازم و با آن کار کنم یا اینکه SC موجود در فرم اول را publiuc تعریف کنم و از همان استفاده کنم. آیا این کار ئوم اصول برنامه نویسی شی گرا را نقض نمی کند.
با تشکر

Soroush.Sarabi
دوشنبه 24 اسفند 1388, 10:24 صبح
دوسا عزیز اگر اطلاعات مورد نیاز در فرم 2 هم مثل فرم 1 است که میتونی همون نمونه رو به Constructor

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

گرایی است.

mehdi.mousavi
دوشنبه 24 اسفند 1388, 12:55 عصر
سلام.

@smt1383 (http://barnamenevis.org/forum/member.php?u=7117): اگر یک سیستم رو Modular ببینید، دیگه از این سوالات نمی کنید. اینکه منطق کارکردن با Serial Port رو در یک کلاس Encapsulate کرده اید، کار پسندیده ای هستش. اما اینکه UI مستقیما داره با این کلاس کار میکنه، قابل قبول نیست. در واقع، شما باید Module ای داشته باشید که بر اساس "فرامینی" که از UI دریافت میکنه، کار مورد نظر رو روی Serial Post انجام بده. اصلا چه دلیلی داره که کد Serial Port شما توی همون Main Thread فراخوانی بشه؟؟؟ به اعتقاد من، باید یک Worker Thread این وظیفه رو به دوش بکشه و فقط دستوراتی کنترلی از بیرون دریافت کنه و کار خودش رو پیش ببره. به بیان دیگه، شما Modeling ای برای نرم افزارتون ندارید و همه چیز رو به چشم UI نگاه می کنید... Office Automation Model این مشکل شما (و بسیاری دیگه) رو بخوبی رفع میکنه. دنبال مقاله Omar Al Zabir توی CodeProject (یا MSDN) در مورد OAM بگردید، به پاسخ خودتون خواهید رسید.

@Soroush.Sarabi (http://barnamenevis.org/forum/member.php?u=107516): اگر قرار باشه 3 تا فرم دیگه هم با اون کلاس کار کنن، شما می خواهید Instance به کلاس Serial Port رو به اون سه تا کلاس دیگه هم ارسال کنید؟؟؟ اینطوری در نهایت یک Spaghetti Code دارید که هر کلاسی توش، میتونه و اجازه داره با هر کلاس دیگه کار کنه، Refactoring رو بسیار سخت میکنه و در کل Maintenance چنین کدی، کابوسه. اصول شی گرایی به تنهایی نمیتونه کارساز باشه، بلکه این نحوه طراحی یک سیستم نرم افزاری هستش که باعث میشه اون اصول، توی یک سیستم، خوب بکار گرفته بشن.

در نهایت، به این نکته دقت کنید: همونطوریکه در DataBase ها برخی اوقات denormalization میتونه بسیار مفید و چشم گیر باشه، در مورد متغیرهای Global هم اینچنین هستش. هرگز نمیشه گفت که استفاده از Global Variable ها بده، این کاملا بستگی به شرایطی داره که در اون قرار گرفته ایم. اما بعنوان یک قانون کلی، بر حذر بودن از این نوع متغیرها (و دسترسیها)، کار صحیحی هستش. در واقع، اگر از یک Modeling خوب در نرم افزار استفاده کنید، دیگه هرگز نیازی به مطرح کردن چنین پرسشهایی نخواهید داشت.

موفق باشید.

smt1383
دوشنبه 24 اسفند 1388, 15:21 عصر
خیلی ممنون آقای موسوی
البته این توضیح را بدهم که موضوع به این صورت است که در فرم اصلی به صورت پریودیک اطلاعات تعدادی سنسور خوانده شده و نمایش داده می شود و در فرم دوم کاربر می تواند هر کدام از سنسورها را خاموش یا روشن کند یا آلارم آن را فعال یا غیر فعال کند. کلیه مراحل ارتباط با پورت سریال و دریافت اطلاعات سنسورها یا فعال و غیر فعال کردن سنسورها در کلاس Serial_communication انجام می شود.
البته من مقاله ای با عنوان OAM راپیدا نکردم.

mehdi.mousavi
دوشنبه 24 اسفند 1388, 15:29 عصر
خیلی ممنون آقای موسوی
البته این توضیح را بدهم که موضوع به این صورت است که در فرم اصلی به صورت پریودیک اطلاعات تعدادی سنسور خوانده شده و نمایش داده می شود و در فرم دوم کاربر می تواند هر کدام از سنسورها را خاموش یا روشن کند یا آلارم آن را فعال یا غیر فعال کند. کلیه مراحل ارتباط با پورت سریال و دریافت اطلاعات سنسورها یا فعال و غیر فعال کردن سنسورها در کلاس Serial_communication انجام می شود.
البته من مقاله ای با عنوان OAM راپیدا نکردم.

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

در هر حال، این یکی از اون دو مقاله ای بود که بهش اشاره کردم. (http://msdn.microsoft.com/en-us/library/ms973253.aspx)

موفق باشید.

Soroush.Sarabi
سه شنبه 25 اسفند 1388, 14:13 عصر
سلام.

@Soroush.Sarabi (http://barnamenevis.org/forum/member.php?u=107516): اگر قرار باشه 3 تا فرم دیگه هم با اون کلاس کار کنن، شما می خواهید Instance به کلاس Serial Port رو به اون سه تا کلاس دیگه هم ارسال کنید؟؟؟ اینطوری در نهایت یک Spaghetti Code دارید که هر کلاسی توش، میتونه و اجازه داره با هر کلاس دیگه کار کنه، Refactoring رو بسیار سخت میکنه و در کل Maintenance چنین کدی، کابوسه. اصول شی گرایی به تنهایی نمیتونه کارساز باشه، بلکه این نحوه طراحی یک سیستم نرم افزاری هستش که باعث میشه اون اصول، توی یک سیستم، خوب بکار گرفته بشن.

موفق باشید.

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



---------------MICROSOFT MCP,MCTS-----------------

(http://www.soroush-sarabi.com)

mehdi.mousavi
سه شنبه 25 اسفند 1388, 14:37 عصر
دوست عزیز این نکته ای که من اشاره کردم فقط برای این موضوع بود و برای پاسخ به این طرح سوال نسخه کلی برای همه برنامه ها نپیچیدم در ضمن منظورتون از اینکه هر کلاسی توش، میتونه و اجازه داره با هر کلاس دیگه کار کن چیه چون من درست متوجه نشدم، یعنی منظورتون اینکه توی یک کلاس نباید با کلاس های دیگر کارکرد؟


سلام.
در مورد همین کلاس صحبت کنیم. فرض کنید سه فرم دیگه هم قراره با سریال پورت کار کنن. به نظر شما چطور باید اینکار انجام بشه؟ شما گفتید باید Instance از اون کلاس، به سه فرم دیگه هم ارسال بشه (در ctor)، یا Instance جدیدی از اون کلاس در فرمهای جدید ایجاد بشه. درسته؟

من گفتم این روش مطلقا صحیح نیست. حتی اگر قرار باشه فقط یکبار این Instance به کلاس مزبور پاس داده بشه. (داریم در مورد مساله Serial Port صحبت میکنیم). چرا؟ چون این دقیقا میره به سمت تولید یک کد error-prone، تولید یک کد اسپاگتی.

برای حال این معضل، باید یک Controller ای برای کار با Serial Port داشته باشیم. میتونیم یک Message Bus داشته باشیم که فرامین مورد نظر رو "هر ماژول و کلاسی" که مایل بود، در صف مورد نظر بذاره و Controller به اون پیامها رسیدگی کنه. یکی از این پیامها، "ارسال فلان اطلاعات روی پورت" میتونه باشه. اینطوری، من چیزی رو بین فرمها Share نکردم، اما در عین حال، سیستمی ساختم که با توجه به قوانین Object-Oriented کار خواهد کرد و هرگز error-prone نیست. کد بهم نمیپیچه و خیلی سر راست و شسته رفته هستش. کاملا Thread-Safe بوده و Maintenance اش خیلی راحته.

ممکنه این سوال پیش بیاد که چطوری همه به اون Message Bus دسترسی دارن؟ برای این مساله، باید یک کلاس Factory داشته باشیم، که Instance مورد نظر از این Bus رو به دست هر کسی که مایل بود بده.

تصور کنید سیستمی رو که بدین شکل طراحی شده باشه (مثل خود ویندوز، سیستمهای مخابراتی و ...).... هر ماژولی، خودش مجزا کار میکنه، و اینها توسط Well Defined Interfaces باهم دیگه در ارتباطن... منظورم از Interface، اینترفیس های زبان برنامه نویسی نیست. منظورم متودهای "محدود، مشخص، کلی و کارآمد" هستن که برای کار با این Bus در نظر گرفته میشه.

شما SendMessage و PostMessage رو از ویندوز بگیرید، هیچی از ویندوز باقی نمیمونه. تمام این تشکیلات روی این دو متود سوارن... هر کسی، هر موقع نیاز داشت، میتونه PostMessage کنه و دستوری رو در صف پیامهای ویندوز قرار بده. در نهایت، یک کنترلی داره این پیامها رو از توی صف در میاره و بهش واکنش نشون میده. غیر این بود، سنگ رو سنگ بند نمیشد.

موفق باشید.

پاورقی: امیدوارم تونسته باشم منظورم رو بیان کنم. در واقع، قوانین Object Oriented هیچگاه به تنها کارساز نبوده و راهگشا نیست. شما باید نگاه Modular به سیستم داشته باشید...