0

سادگی یا دورویی؟

 
samsam
samsam
کاربر طلایی1
تاریخ عضویت : بهمن 1387 
تعداد پست ها : 50672
محل سکونت : یزد

سادگی یا دورویی؟

حتما تا به حال دقت کرده اید که مغز انسان چه پیچیدگی های عجیبی دارد. به سادگی قادر است چیزهایی را که هیچ ربطی به هم ندارند، به هم ربط دهد، تعداد و مقدار را به سادگی کنار هم قرار دهد یا حتی با هم جمع کند. زبان های شیء گرا1 که با هدف پیاده سازی مدل طبیعی پا به عرصه وجود گذاشته اند نیز در اصل به دنبال ساده سازی کدنویسی و پیاده سازی هر چه بهتر دنیای واقعی هستند. بیایید یک تلفنچی را مثال بزنیم؛ این شخص ممکن است به خاطر فشار شدید کاری در یک روزگرم تابستانی، به شدت از کوره در رفته باشد و حتی چند تماس را با بدخلقی تمام پاسخ داده باشد، اما وقتی یک تماس شخصی از سوی یکی از اعضای خانواده اش دریافت می کند، اخلاق خوشی از خود نشان می دهد و صورت دیگری از خود را بروز می دهد. این قابلیت، یعنی چندریختی2 یکی از ویژگی های پیاده شده در برنامه نویسی شیء گرا است. انواع مختلفی از چندریختی ممکن است وجود داشته باشد، یکی از آن ها که مثال زدیم، بازنویسی رفتار3 است. یکی دیگر از انواع بازنویسی، بازنویسی عملگرها4 است که به آن بیشتر خواهیم پرداخت. هدف از بازنویسی عملگرها، تغییر رفتار عملگرهاست، تا جایی که عملگرها با توجه نوع عملوندها رفتاری متفاوتی از خود نشان بدهند. برخی از این عملوندها را خود زبان برنامه نویسی بازنویسی کرده است، اما برخی دیگر را برنامه نویس به دلخواه خود بازنویسی می کند. بگذارید یک مثال بزنیم تا بهتر مشخص شود چه کاری می خواهیم انجام بدهیم. عملگر جمع (+) را فرض کنید. در زبان سی شارپ اگر 2 عملوند عدد صحیح از نوع int باشد، خروجی int خواهد بود و 2 عدد را جمع می کند و حاصل را بر می گرداند، حالا اگر 2 عملوند از نوع رشته متنی باشند، چه؟ در اینجا زبان سی شارپ یک بازنویسی عملگر درونی دارد و در آن، 2 رشته ورودی را با هم ترکیب می کند و نتیجه به صورت یک رشته متنی باز می گردد، مثلا اگر بنویسیم: "jamejam" + " click!" خروجی عبارت jamejam click! خواهد بود، در ادامه نحوه بازنویسی عملگرها را برای کلاسی که خودمان تعریف کردیم بررسی می کنیم. پیش از اینکه نحوه بازنویسی کردن عملگرها را توضح دهیم، لازم است ببینیم کدام عملگرها قابلیت بازنویسی دارند: عملگرهای دودویی (عملگرهایی که به دو عملوند (operand) برای اجرا شدن نیاز دارند)، مانند: + (جمع)، - (تفریق)، *، /، %، &، |، ^، «« و »» . عملگرهای یگانی (عملگرهایی که تنها به یک عملوند نیاز دارند)، مانند: + (مثبت)، - (منفی)، !، ~، ++، --، true و false. بقیه عملگرها قابلیت باز نویسی ندارند ولی بعضی از آن ها را می توان به صورت دیگری بازنویسی کرد؛ مثلا عملگر += خلاصه عملگر + است، که خود + قابلیت بازنویسی را دارد یا عملگر () (تبدیل نوع یا cast) ، قابل بازنویسی را ندارد، ولی شما با استفاده از explicit و implicit که هر دو از keywordهای سی شارپ هستند می توانید آن را بازنویسی کنید. کار خود را با یک مثال شروع می کنیم. ما یک کلاس به اسم matrix تعریف کردیم. این کلاس عملیات خاصی را روی یک ماتریس انجام می دهد. مثلا دترمینان یک ماتریس را حساب می کند، یا 2ماتریس را جمع یا ضرب می کند و ... . حال فرض کنید بدون استفاده از بازنویسی عملگرها بخواهیم این کلاس را بنویسیم. برای جمع 2 ماتریکس، 2 روش وجود دارد، نخست این که یک متد استاتیک تعریف کنیم تا 2 ماتریس را جمع کند و حاصل را به صورت یک ماتریس برگرداند. این متد به صورت زیر خواهد بود: system.math.matrix mx1 = new system.math.matrix(4,5); system.math.matrix mx2 = new system.math.matrix(4,5); system.math.matrix result = system.math.matrix.add(mx1, mx2); این روش اشتباه نیست، اما بگذارید کمی آن را به تر بنویسیم. در کلاس ماتریکس متد add را از حالت استاتیک در می آوریم، و به جای دریافت 2 پارامتر ورودی، یک پارامتر ورودی به آن می دهیم و با خودش جمع می کنیم: mx1.add(mx2); به هرحال این هم یک روش است که به نظر ساده تر و منطقی تر می رسد. حتی از این هم می توان زیباتر نوشت. اینجا همانجایی است که بازنویسی عملگرها وارد صحنه می شود: mx1 = mx1 + mx2; اگر بتوانیم ماتریکس ها را همان طور که روی کاغذ می نویسیم و جمع می زنیم، در کد خود بنویسیم، هم خواندن کد برای ما ساده تر می شود، هم در کار تیمی جلوه بهتری دارد. ما چه کار خواهیم کرد؟ عملگر + (جمع) را برای کلاس ماتریس خودمان بازنویسی می کنیم و به کامپایلر نشان می دهیم که اگر 2 عملوند عملگر + از جنس ماتریس بود، فلان کار را انجام بده. که این فلان کار یعنی 2 ماتریس را با هم جمع کن و خروجی را از نوع ماتریکس برگردان. خوب این هم کار ما را خیلی ساده تر کرد، البته بیشتر برای کسانی که از کلاس ما استفاده می کنند ساده شده است، حال بررسی می کنیم ببینیم این عمل چگونه اتفاق می افتد یعنی کامپایلر از کجا می فهمد که باید هنگام برخورد با +، به سراغ متد خاصی برود و آن را اجرا کند؟ بیایید متدی را تعریف کنیم: public class matrix { public static matrix operator + (matrix mx1, matrix mx2) return mx1.add(mx2); } همان طور که می بینید، در این جا ما عملگر + را به صورت عملگری دوگانه تعریف کرده که 2 پارامتر mx1 و mx2 را دریافت می کند و mx1 را با mx2 جمع کرده و نتیجه را باز می گرداند (با استفاده از متد فرضی add). و در نهایت کد بسیارساده ای خواهیم داشت. اما فراموش نکنید، استفاده از بازنویسی عملگرها، کد را به شدت ساده می کند، اما همین سادگی می تواند کار دست برنامه نویس بدهد. به فرض، اگر عملگر + را برای یک پارامتر از هر نوعی و یک پارامتر از نوع int بگیرید به خاطر تقدم و تاخر پارامترها، c+2 مجاز است، اما 2+c غیر مجاز است چون در ترتیب آرگومان ها، بازنویسی ندارد. این اشتباهات ساده ممکن است صدمات بزرگی به کد نوشته شده بزند و آن را کاملا غیرقابل اعتماد بکند. 

چهار راه برای رسیدن به آرامش:
1.نگاه کردن به عقب و تشکر از خدا  2.نگاه کردن به جلو و اعتماد به خدا  3.نگاه کردن به اطراف و خدمت به خدا  4.نگاه کردن به درون و پیدا کردن خدا

پل ارتباطی : samsamdragon@gmail.com

تالارهای تحت مدیریت :

مطالب عمومی کامپیوتراخبار و تکنولوژی های جدیدسیستم های عاملنرم افزارسخت افزارشبکه

 

شنبه 9 آبان 1388  2:04 PM
تشکرات از این پست
دسترسی سریع به انجمن ها