موضوع مقاله: مدل شیء مؤلفه | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # مدل شیء مؤلفه | مقدمه: مدل شیء مؤلفه با کوته‌نوشت COM یک استاندارد واسط دودویی برای مولفه‌های نرم‌افزاری است که توسط شرکت مایکروسافت در سال ۱۹۹۳ (سال ۱۳۷۲ شمسی) معرفی شد. | ## بخش 1: مدل شیء مؤلفه | از این فناوری برای ایجاد توانمندی «ارتباط بین‌پردازه‌ای» در ایجاد شیء در بسیاری از زبان‌های برنامه‌نویسی استفاده می‌شود. ماهیت COM ایجاد یک روش «خنثی از نظر زبان» برای پیاده‌سازی اشیایی است که قابلیت استفاده در محیطی را دارند که با محیطی که در آن ایجاد شده‌اند متفاوت است، یعنی حتی می‌توان در محدودهٔ بین ماشینی از آن استفاده کرد. برای مولفه‌هایی که به‌خوبی نوشته شده باشند، COM امکان استفاده مجدد از اشیا را بدون هیچ دانشی از پیاده‌سازی درونی آن‌ها می‌دهد، زیرا این فناوری پیاده‌سازهای مولفه را مجبور می‌کند تا «واسطهای خوش‌تعریف» تهیه کنند، که این واسط‌ها از پیاده‌سازی جدا هستند. معانی تخصیص در زبان‌های مختلف متفاوت است، اما این موضوع به این صورت سازگارسازی می‌شوند که اشیا «خودشان» مسئول ساخت خودشان باشند و از بین بردن آن‌ها از طریق شمارش ارجاع انجام می‌شود. شگرد ارجح «ارث‌بری» در COM، ساخت زیرشیءهایی است که به آن‌ها «تماس» شگردی واگذار می‌شوند. COM یک فناوری واسط است که به عنوان یک «فقط استاندارد» در مایکروسافت ویندوز و بنیاد هسته اپل ۱٫۳ و سپس در افزونه‌های واسط برنامه‌نویسی کاربردی (API) تعریف و پیاده‌سازی شده‌است. در بعضی از کاربردها، COM تاحدی به‌وسیله چارچوب دات‌نت مایکروسافت جایگزین شده‌است، و در پشتیبانی از خدمات وب توسط بنیاد ارتباطات ویندوز (WCF) جایگزین شده‌است. COM به دیگر فن‌آوری‌های واسط نرم‌افزار مولفه، مثل CORBA، و جاوابینز سازمانی بسیار شبیه است، اگرچه هرکدام از آن‌ها نقاط قوت و ضعف خودشان را دارند. الگوی COM به منظور توانمندسازی ارتباطات بین پردازشی و ساختن اشیاء به صورت پویا، برای تعداد زیادی از زبان‌های برنامه‌نویسی مورد استفاده قرار گرفته‌است. تلاش‌های قبلی برای توکارسازی مولفه‌های ActiveX در صفحات وب با اینترنت اکسپلورر منجر به مسائلی در زمینه سرایت بدافزار شده‌اند. ورژن‌های جدید اینترنت اکسپلورر قبل از نصب کنترل‌های ActiveX از کاربر اجازه می‌گیرند، و این موضوع به کاربر امکان آن را می‌دهد تا اجازه نصب کنترل‌ها از سایت‌هایی که کاربر به آن‌ها اعتماد ندارد، را ندهد. این موضوع مقدور هست که همه کنترل‌های ActiveX را غیرفعال کنیم، یا فقط تعدادی اندکی که انتخاب شده‌اند را مجاز بدانیم. «پشتیبانی شفاف برای سرورهای خارج‌ از فرآیند COM» هم امنیت نرم‌افزار را، در قالب جداسازی فرایندها، افزایش می‌دهد. این موضوع برای جداسازی زیرسامانه‌های برنامه‌کاربردی بزرگ به فرایندهای مجزا می‌تواند مفید باشد. انزوای فرایند، خرابی حالت در یک فرایند را، از تأثیر مخرب در درستی دیگر فرایندها، محدود می‌کند، زیرا آنها فقط از طریق واسط‌های موکداً تعریف شده ارتباط برقرار می‌کنند؛ بنابراین، فقط زیرسامانه تأثیر پذیرفته، برای بازیابی حالت مجاز، باید راه‌اندازی مجدد گردد. این موضوع برای زیر سامانه‌های موجود در فرایند مشابه درست نیست، چراکه در آن یک اشاره‌گر سرکش در یک زیرسیستم به صورت تصادفی، می‌تواند دیگر زیرسامانه‌ها را خراب کند. جزئیات فنی برنامه‌نویسان COM نرم‌افزارشان را به کمک مولفه‌های مطلع از COM می‌سازند. واسط‌های COM بستگی‌هایی در زبان‌های مختلف مثل C, C++، ویژوال بیسیک، دلفی، پایتون، و دیگر زبان‌های اجرانامه‌نویسی که در بن‌سازه ویندوز پیاده‌سازی شده‌اند دارند. این موضوع امکان فن‌آوری‌هایی مثل برنامه‌نویسی بین‌پردازه‌ای یا حتی برنامه‌نویسی بین‌رایانه‌ای را فراهم می‌کند (که دومی از طریق پشتیبانی از DCOM انجام می‌شود). واسط‌ها همه مولفه‌های COM واسط (سفارشی) IUnknown را پیاده‌سازی می‌کنند، که شگردهایی برای شمارش ارجاع و تبدیل نوع (ریخته‌گری نوع) نمایان می‌سازند. یک واسط سفارشی IUnknown شامل یک اشاره‌گر به جدول شگرد مجازی است، که شامل یک لیست از اشاره‌گرها به توابعی است که توابع اعلان شده در واسط را پیاده‌سازی می‌کنند، و این موضوع به همان ترتیبی انجام می‌شود که در واسط اعلان شده‌اند. از این رو سربار فراخوانی بین‌پردازشی قابل مقایسه با تماس‌های شگرد مجازی در C++ است. این موضوع به واسط‌های اعزامی امکان می‌دهد تا به صورت محلی توسط محدوده گسترده‌تری از زبان‌های برنامه‌نویسی نسبت به واسط‌های سفارشی دسترسی بیابند. کلاس‌ها یک کلاس COM یا «coclass» یک پیاده‌سازی عینی از یک یا بیشتر واسط است، و خیلی به کلاس‌های موجود در زبان‌های برنامه‌نویسی شیءگرا شبیه است. مثل خیلی از زبان‌های شیءگرا، COM قابلیت جداسازی واسط از پیاده‌سازی را فراهم می‌بیند. این تفکیک مخصوصاً در COM زیاد است، زیرا در آن اشیا را نمی‌توان به صورت مستقیم به اشیا دسترسی یافت، بلکه فقط از طریق واسط شان قابل دسترسی هستند. COM از موضوع چندین پیاده‌سازی برای یک واسط پشتیبانی می‌کند، که در نتیجه آن کارخواه‌ها در زمان اجرا می‌توانند انتخاب کنند که کدام پیاده‌سازی از یک واسط را نمونه برداری کنند. | ## بخش 2: مدل شیء مؤلفه | زبان تعریف واسط و کتابخانه‌های نوع کتابخانه‌های نوع شامل فراداده‌هایی هستند که می‌توانند انواع COM را نمایش دهند. فایل‌های IDL تعریف کننده کلاس‌ها، واسط‌ها، ساختارها، فهرست‌شمارای شیءگرا، و دیگر انواع تعریف شده توسط کاربر هستند و این تعریف‌ها به حالت مستقل از زبان هستند. IDL از ویژگی‌های قلابی، قبل از اعلان‌ها پشتیبانی می‌کند، تا اطلاعات اضافی را تهیه ببیند مثلاً GUIDهای واسط، و رابطه بین پارامترهای اشاره‌گر و فیلدهای طول. این پراکسی شامل سه‌رسید شگرد برای تبدیل تماس COM به تماس‌های رویه دوردست است تا به DCOM امکان ارتباطات بیرون از فرایند را بدهد. فایل‌های TLB شامل فراداده‌های دودویی است که قابلیت پردازش توسط کامپایلرهای زبانی مختلف و محیط‌های زمان‌اجرای مختلف (مثل VB، دلفی، دات‌نت، و غیره) را دارد، و در نتیجه ساختارهای خاص‌زبانه‌ای تولید می‌شود که نمایش‌دهنده انواع COM تعریف شده در TLB هستند. COM به عنوان یک چارچوب شیء به دلیل آنکه COM یک چارچوب زمان‌اجرا است، انواع را باید به صورت منفرد در زمان‌اجرا تشخیص داد و تعیین کرد. برای آنکه اطلاعات انواع COM هم در زمان‌اجرا و هم‌زمان کامپایل دردسترس باشند، COM از کتابخانه‌های نوع استفاده می‌کند. این موضوع از طریق استفاده مؤثر از «کتابخانه‌های نوع» به دست می‌آید، که COM از طریق یک چارچوب پویا برای تعامل با اشیا به توانمندی‌اش می‌رسد. فایل‌های IDL شامل واسط‌ها و کلاس‌های COM به فایل‌های کتابخانه نوع (TLB) کامپایل می‌شوند، که بعداً در زمان‌اجرا توسط کارخواه‌ها قابل تجزیه اند، تا تعیین کنند که کدام یک پشتیبانی شیء را واسط سازی می‌کنند، و شگردهای واسط شیء را فراخوانی می‌کنند. شمارش ارجاع همه اشیای COM از شمارش ارجاع برای مدیریت زمان‌زندگی اشیاء استفاده می‌کنند. اشیای COM آنوقت مسئول خالی‌سازی حافظه خودشان اند و این موضوع وقتی رخ می‌دهد که تعداد ارجاع‌ها به صفر کاهش می‌یابد. زبان‌های خاص (مثل ویژوال بیسیک) امکان شمارش خودکار ارجاع را فراهم می‌کنند، که در نتیجه آن توسعه‌دهندگان اشیای COM نیازی به نگهداری صریح هیچ شمارشگر ارجاع درونی در کد منبع‌شان را ندارند. در C++، یک کدنویس برای مدیریت تعداد ارجاع‌ها، یا از انجام شمارش صریح ارجاع استفاده می‌کند، یا از اشاره‌گرهای هوشمند استفاده می‌کند، تا به صورت خودکار مدیریت تعداد ارجاع انجام شود. در زیر راهبردهایی برای زمان استفاده فراخوانی AddRef و Release روی اشیای COM آمده‌است: توابع و شگردهایی که ارجاع‌های واسط را برمی‌گردانند (از طریق مقدار بازگشتی یا از طریق پارامتر "out") باید تعداد ارجاع شیء بازگشتی را قبل از بازگردانی افزایش دهند. Release باید قبل از آنکه اشاره‌گر رونویسی شود یا از دسترس خارج شود، روی یک اشاره‌گر واسط، صدا زده شود. اگر یک کپی روی اشاره‌گر ارجاع واسط انجام شود، AddRef باید روی آن اشاره‌گر صدازده شود. همه تعداد ارجاع‌ها به اشیای دوردست روی یک خط ارسال نمی‌شوند؛ بلکه یک پراکسی فقط یک ارجاع را روی شیء دوردست نگه‌می‌دارد و تعداد ارجاع محلی خودش را نگهداری می‌کند. این موضوع توسعه‌دهندگان کاربردی کارخواه COM را از نیاز برای نگهداری مستقیم تعداد ارجاع محافظت می‌کند، این کار از طریق تهیه اشیای اشاره‌گر هوشمند انجام می‌شود. برنامه‌نویسی COM یک استاندارد دودویی منکر زبان است، که می‌توان آن را در هر زبان برنامه‌نویسی که قادر به فهم و پیاده‌سازی انواع داده و واسط‌های دودویی تعریف شده اش هستند، توسعه داد. پیاده‌سازی‌های COM مسئول ورود و خروج از محیط COM، نمونه‌برداری و شمارش-ارجاع اشیای COM، پزسمان از اشیا برای واسط‌های پشتیبانی شده، و نیز رسیدگی به حالت استثنا هستند. کتابخانه‌های COM از رجیستری برای تعیین محل یا کتابخانه‌های محلی صحیح برای هر شیء COM یا محل شبکه‌ای برای یک خدمت دوردست استفاده می‌کنند. در عوض، فراداده و CLSIDهای کلاس‌های پیاده‌سازی شده در مولفه در صورت‌کد اسمبلی اعلان می‌شوند (به کمک XML توصیف می‌شوند) یا به صورت یک منبع در اجراپذیر ذخیره می‌شوند، یا به صورت یک فایل مجزا همراه مولفه نصب می‌گردند. این موضوع امکان آن را فراهم می‌کند تا نسخه‌های مختلفی از یک مولفه مشابه در دایرکتوری‌های مختلف نصب گردند، و توسط صورت‌کدهای خاص خودشان توصیف شوند، مثلاً در استقرار XCOPY این موضوع وجود دارد. موقعی که کارخانه کلاس COM بخواهد یک کلاس را نمونه‌برداری کند، بافت فعال‌سازی اول بررسی می‌شود تا ببیند آیا یک پیاده‌سازی از CLSID را می‌توان یافت یا نه. این موضوع نیازی به بایگانی DLL یا GUID در رجیستری سامانه ندارد، و از فایل‌های صورت‌کد هم استفاده نمی‌کند. این فرایند مشابهی است که موقعی که به صورت درونی نمونه‌های مولفه‌های COM رجیستر شده را می‌سازیم، استفاده می‌شود. اما می‌تواند اشیای درونی را بسازد (که ممکن است اصلاً رجیستر نشود)، و ارجاع‌ها به واسط‌های آن را به دست چیز بیرونی بدهد، و این کار را به کمک دانش خصوصی خودش انجام دهد. | ## بخش 3: مدل شیء مؤلفه | اشیای برون‌پردازه‌ای یا راه‌دور از صف‌آرایی برای پیاپی‌سازی تماس‌های شگردی، و مقادیر بازگشتی روی مرزهای پردازه، یا شبکه استفاده می‌کنند. این صف‌آرایی برای کارخواه قابل دیدن نیست، زیرا او به شیء به این صورت دسترسی دارد که مثل آن است که این یک شیء محلی درون پردازه‌ای است. سه نوع آپارتمان در COM وجود دارد: آپارتمان تک-ریسه‌ای (STA)، آپارتمان چند-ریسه‌ای (MTA) و آپارتمان خنثی از نظر ریسه. هر آپارتمان نمایش‌دهنده یک سازکار است که به کمک آن حالت درونی شیء را می‌توان بین چندین ریسه همزمان‌سازی کرد. یک پردازه می‌تواند شامل چندین شیء COM باشد، که بعضی از آن‌ها از STA استفاده می‌کنند، بقیه می‌توانند از MTA استفاده کنند. همهٔ ریسه‌هایی که به اشیای COM دسترسی می‌یابند، به صورت مشابه در یک آپارتمان زندگی می‌کنند. انتخاب نوع آپارتمان برای اشیای COM و ریسه‌ها در زمان‌اجرا تعیین می‌شود، و این موضوع قابل تغییر نیست. در این ترتیب، تماس‌های شگردی از ریسه‌های بیرون از آپارتمان صف‌آرایی می‌شوند، و به صورت خودکار توسط سامانه صف‌دهی می‌شوند (یعنی از طریق صف پیام ویندوز استاندارد). از این رو، زمان‌اجرای COM هم‌زمانی خودکار فراهم می‌کند، و این موضوع از این اطمینان حاصل می‌کند که هر فراخوانی شگرد از یک شیء همیشه تا تکمیل اجرا می‌گردد، قبل از آنکه شگرد دیگری فراخوانی شود. اشیای COM از این رو نیاز به اجرای همزمانی خاص خود را دارند تا در موقع دسترسی همزمان از چندین ریسه، از ایجاد وضعیت رقابت جلوگیری شود. اشیا و ریسه‌هایی که به یک آپارتمان تعلق دارند، از قواعد دسترسی به ریسه مشابهی پیروی می‌کنند. فراخوانی شگردی که در داخل آپارتمان مشابهی انجام می‌شوند، به صورت مستقیم انجام می‌شوند، یعنی هیچ کمکی از جانب COM نمی‌گیرند. فراخوانی شگرد که بین آپارتمان‌ها انجام می‌شوند، از طریق صف‌آرایی به دست می‌آیند. انتقادات به دلیل آنکه COM پیاده‌سازی واقعاً پیچیده‌ای دارد، ممکن است برنامه‌نویسان توسط بعضی از مسائل «لوله‌کشی» پریشان شوند. پمپ‌کردن پیام موقعی که یک STA نمونه‌برداری می‌شود، یک پنجرهٔ پنهان را می‌سازد که از آن برای راه‌یابی برای پیام‌های داخل آپارتمانی یا داخل پردازه‌ای استفاده می‌شود. در ورژن‌های قدیمی ویندوز، ناتوانی در انجام این کار می‌توانست منجر به بن‌بست‌های سطح سامانه شود. این موضوع توسط بعضی از APIهای ویندوز که COM را به عنوان بخشی از پیاده‌سازی شان راه‌اندازی می‌کردند، پیچیده‌تر می‌شد، و این کار باعث «نشت» جزئیات پیاده‌سازی می‌شود. شمارش ارجاع اگر دو یا بیشتر شیء به صورت چرخه‌ای ارجاع‌دهی شوند، شمارش ارجاع در داخل COM می‌تواند منجر به مشکل‌هایی شود. طراحی برنامه‌کاربردی باید این موضوع را درنظر بگیرد، و درنتیجه آن اشیا نباید یتیم باقی بمانند. اگر مدل «غرق وقعه» COM استفاده شود، اشیا ممکن است با وجود تعداد ارجاع فعال از بین بروند. به دلیل آنکه شیءای که وقعه را بیرون داده‌است، نیاز به یک ارجاع به شیءای دارد که به وقعه واکنش نشان می‌دهد، تعداد ارجاع دومی هیچگاه به صفر نمی‌رسد. ارجاع‌های دایره‌وار معمولاً یا توسط فن «خاتمهٔ خارج از باند»، یا توسط فن «هویت جداکننده» شکسته می‌شوند. در تکنیک خاتمه خارج از باند، یک شیء یک شگرد را نمایان می‌سازد که موقعی که صدازده شود، آن شیء را مجبور می‌سازد که ارجاع‌هایش به دیگر اشیاء را از بین ببرد، و از این رو چرخه را بشکند. در فن هویت جداکننده، یک پیاده‌سازی منفرد، دو شیء COM را نمایان می‌سازد (که به آن هویت گفته می‌شود). این موضوع باعث ایجاد یک ارجاع ضعیف، بین اشیای COM می‌شود، و از یک چرخه ارجاع جلوگیری می‌کند. جهنم DLL به دلیل آنکه مولفه‌های COM درون-پردازه‌ای در فایل‌های DLL پیاده‌سازی می‌شوند، و رجیسترکردن تنها به یک ورژن منفرد برای هر CLSID امکان حضور می‌دهد، آن‌ها ممکن است در بعضی حالات در معرض اثر «جهنم DLL» قرار گیرند. | ## جمع‌بندی | توانمندی COMهای بدون رجیستری این مسئله را برای مولفه‌های درون-پردازه‌ای حذف می‌کند؛ اما توانمندی COM بدون رجیستری برای سرورهای برون-پردازه‌ای در دسترس نیستند.